mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-24 09:11:23 -06:00
Initial work for G-code sender and more intensive usage of Boost
This commit is contained in:
parent
43cbad8867
commit
11dd67ab34
1649 changed files with 1860 additions and 1642 deletions
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
Copyright 2008 Intel Corporation
|
||||
|
||||
Use, modification and distribution are subject to the Boost Software License,
|
||||
Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt).
|
||||
*/
|
||||
#ifndef BOOST_POLYGON_RECTANGLE_FORMATION_HPP
|
||||
#define BOOST_POLYGON_RECTANGLE_FORMATION_HPP
|
||||
namespace boost { namespace polygon{
|
||||
|
||||
namespace rectangle_formation {
|
||||
template <class T>
|
||||
class ScanLineToRects {
|
||||
public:
|
||||
typedef T rectangle_type;
|
||||
typedef typename rectangle_traits<T>::coordinate_type coordinate_type;
|
||||
typedef rectangle_data<coordinate_type> scan_rect_type;
|
||||
private:
|
||||
|
||||
typedef std::set<scan_rect_type, less_rectangle_concept<scan_rect_type, scan_rect_type> > ScanData;
|
||||
ScanData scanData_;
|
||||
bool haveCurrentRect_;
|
||||
scan_rect_type currentRect_;
|
||||
orientation_2d orient_;
|
||||
typename rectangle_traits<T>::coordinate_type currentCoordinate_;
|
||||
public:
|
||||
inline ScanLineToRects() : scanData_(), haveCurrentRect_(), currentRect_(), orient_(), currentCoordinate_() {}
|
||||
|
||||
inline ScanLineToRects(orientation_2d orient, rectangle_type model) :
|
||||
scanData_(orientation_2d(orient.to_int() ? VERTICAL : HORIZONTAL)),
|
||||
haveCurrentRect_(false), currentRect_(), orient_(orient), currentCoordinate_() {
|
||||
assign(currentRect_, model);
|
||||
currentCoordinate_ = (std::numeric_limits<coordinate_type>::max)();
|
||||
}
|
||||
|
||||
template <typename CT>
|
||||
inline ScanLineToRects& processEdge(CT& rectangles, const interval_data<coordinate_type>& edge);
|
||||
|
||||
inline ScanLineToRects& nextMajorCoordinate(coordinate_type currentCoordinate) {
|
||||
if(haveCurrentRect_) {
|
||||
scanData_.insert(scanData_.end(), currentRect_);
|
||||
haveCurrentRect_ = false;
|
||||
}
|
||||
currentCoordinate_ = currentCoordinate;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template <class CT, class ST, class rectangle_type, typename interval_type, typename coordinate_type> inline CT&
|
||||
processEdge_(CT& rectangles, ST& scanData, const interval_type& edge,
|
||||
bool& haveCurrentRect, rectangle_type& currentRect, coordinate_type currentCoordinate, orientation_2d orient)
|
||||
{
|
||||
typedef typename CT::value_type result_type;
|
||||
bool edgeProcessed = false;
|
||||
if(!scanData.empty()) {
|
||||
|
||||
//process all rectangles in the scanData that touch the edge
|
||||
typename ST::iterator dataIter = scanData.lower_bound(rectangle_type(edge, edge));
|
||||
//decrement beginIter until its low is less than edge's low
|
||||
while((dataIter == scanData.end() || (*dataIter).get(orient).get(LOW) > edge.get(LOW)) &&
|
||||
dataIter != scanData.begin())
|
||||
{
|
||||
--dataIter;
|
||||
}
|
||||
//process each rectangle until the low end of the rectangle
|
||||
//is greater than the high end of the edge
|
||||
while(dataIter != scanData.end() &&
|
||||
(*dataIter).get(orient).get(LOW) <= edge.get(HIGH))
|
||||
{
|
||||
const rectangle_type& rect = *dataIter;
|
||||
//if the rectangle data intersects the edge at all
|
||||
if(rect.get(orient).get(HIGH) >= edge.get(LOW)) {
|
||||
if(contains(rect.get(orient), edge, true)) {
|
||||
//this is a closing edge
|
||||
//we need to write out the intersecting rectangle and
|
||||
//insert between 0 and 2 rectangles into the scanData
|
||||
//write out rectangle
|
||||
rectangle_type tmpRect = rect;
|
||||
|
||||
if(rect.get(orient.get_perpendicular()).get(LOW) < currentCoordinate) {
|
||||
//set the high coordinate perpedicular to slicing orientation
|
||||
//to the current coordinate of the scan event
|
||||
tmpRect.set(orient.get_perpendicular().get_direction(HIGH),
|
||||
currentCoordinate);
|
||||
result_type result;
|
||||
assign(result, tmpRect);
|
||||
rectangles.insert(rectangles.end(), result);
|
||||
}
|
||||
//erase the rectangle from the scan data
|
||||
typename ST::iterator nextIter = dataIter;
|
||||
++nextIter;
|
||||
scanData.erase(dataIter);
|
||||
if(tmpRect.get(orient).get(LOW) < edge.get(LOW)) {
|
||||
//insert a rectangle for the overhang of the bottom
|
||||
//of the rectangle back into scan data
|
||||
rectangle_type lowRect(tmpRect);
|
||||
lowRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
lowRect.set(orient.get_direction(HIGH), edge.get(LOW));
|
||||
scanData.insert(nextIter, lowRect);
|
||||
}
|
||||
if(tmpRect.get(orient).get(HIGH) > edge.get(HIGH)) {
|
||||
//insert a rectangle for the overhang of the top
|
||||
//of the rectangle back into scan data
|
||||
rectangle_type highRect(tmpRect);
|
||||
highRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
highRect.set(orient.get_direction(LOW), edge.get(HIGH));
|
||||
scanData.insert(nextIter, highRect);
|
||||
}
|
||||
//we are done with this edge
|
||||
edgeProcessed = true;
|
||||
break;
|
||||
} else {
|
||||
//it must be an opening edge
|
||||
//assert that rect does not overlap the edge but only touches
|
||||
//write out rectangle
|
||||
rectangle_type tmpRect = rect;
|
||||
//set the high coordinate perpedicular to slicing orientation
|
||||
//to the current coordinate of the scan event
|
||||
if(tmpRect.get(orient.get_perpendicular().get_direction(LOW)) < currentCoordinate) {
|
||||
tmpRect.set(orient.get_perpendicular().get_direction(HIGH),
|
||||
currentCoordinate);
|
||||
result_type result;
|
||||
assign(result, tmpRect);
|
||||
rectangles.insert(rectangles.end(), result);
|
||||
}
|
||||
//erase the rectangle from the scan data
|
||||
typename ST::iterator nextIter = dataIter;
|
||||
++nextIter;
|
||||
scanData.erase(dataIter);
|
||||
dataIter = nextIter;
|
||||
if(haveCurrentRect) {
|
||||
if(currentRect.get(orient).get(HIGH) >= edge.get(LOW)){
|
||||
if(!edgeProcessed && currentRect.get(orient.get_direction(HIGH)) > edge.get(LOW)){
|
||||
rectangle_type tmpRect2(currentRect);
|
||||
tmpRect2.set(orient.get_direction(HIGH), edge.get(LOW));
|
||||
scanData.insert(nextIter, tmpRect2);
|
||||
if(currentRect.get(orient.get_direction(HIGH)) > edge.get(HIGH)) {
|
||||
currentRect.set(orient, interval_data<coordinate_type>(edge.get(HIGH), currentRect.get(orient.get_direction(HIGH))));
|
||||
} else {
|
||||
haveCurrentRect = false;
|
||||
}
|
||||
} else {
|
||||
//extend the top of current rect
|
||||
currentRect.set(orient.get_direction(HIGH),
|
||||
(std::max)(edge.get(HIGH),
|
||||
tmpRect.get(orient.get_direction(HIGH))));
|
||||
}
|
||||
} else {
|
||||
//insert current rect into the scanData
|
||||
scanData.insert(nextIter, currentRect);
|
||||
//create a new current rect
|
||||
currentRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
currentRect.set(orient, interval_data<coordinate_type>((std::min)(tmpRect.get(orient).get(LOW),
|
||||
edge.get(LOW)),
|
||||
(std::max)(tmpRect.get(orient).get(HIGH),
|
||||
edge.get(HIGH))));
|
||||
}
|
||||
} else {
|
||||
haveCurrentRect = true;
|
||||
currentRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
currentRect.set(orient, interval_data<coordinate_type>((std::min)(tmpRect.get(orient).get(LOW),
|
||||
edge.get(LOW)),
|
||||
(std::max)(tmpRect.get(orient).get(HIGH),
|
||||
edge.get(HIGH))));
|
||||
}
|
||||
//skip to nextIter position
|
||||
edgeProcessed = true;
|
||||
continue;
|
||||
}
|
||||
//edgeProcessed = true;
|
||||
}
|
||||
++dataIter;
|
||||
} //end while edge intersects rectangle data
|
||||
|
||||
}
|
||||
if(!edgeProcessed) {
|
||||
if(haveCurrentRect) {
|
||||
if(currentRect.get(orient.get_perpendicular().get_direction(HIGH))
|
||||
== currentCoordinate &&
|
||||
currentRect.get(orient.get_direction(HIGH)) >= edge.get(LOW))
|
||||
{
|
||||
if(currentRect.get(orient.get_direction(HIGH)) > edge.get(LOW)){
|
||||
rectangle_type tmpRect(currentRect);
|
||||
tmpRect.set(orient.get_direction(HIGH), edge.get(LOW));
|
||||
scanData.insert(scanData.end(), tmpRect);
|
||||
if(currentRect.get(orient.get_direction(HIGH)) > edge.get(HIGH)) {
|
||||
currentRect.set(orient,
|
||||
interval_data<coordinate_type>(edge.get(HIGH),
|
||||
currentRect.get(orient.get_direction(HIGH))));
|
||||
return rectangles;
|
||||
} else {
|
||||
haveCurrentRect = false;
|
||||
return rectangles;
|
||||
}
|
||||
}
|
||||
//extend current rect
|
||||
currentRect.set(orient.get_direction(HIGH), edge.get(HIGH));
|
||||
return rectangles;
|
||||
}
|
||||
scanData.insert(scanData.end(), currentRect);
|
||||
haveCurrentRect = false;
|
||||
}
|
||||
rectangle_type tmpRect(currentRect);
|
||||
tmpRect.set(orient.get_perpendicular(), interval_data<coordinate_type>(currentCoordinate,
|
||||
currentCoordinate));
|
||||
tmpRect.set(orient, edge);
|
||||
scanData.insert(tmpRect);
|
||||
return rectangles;
|
||||
}
|
||||
return rectangles;
|
||||
|
||||
}
|
||||
|
||||
template <class T>
|
||||
template <class CT>
|
||||
inline
|
||||
ScanLineToRects<T>& ScanLineToRects<T>::processEdge(CT& rectangles, const interval_data<coordinate_type>& edge)
|
||||
{
|
||||
processEdge_(rectangles, scanData_, edge, haveCurrentRect_, currentRect_, currentCoordinate_, orient_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} //namespace rectangle_formation
|
||||
|
||||
template <typename T, typename T2>
|
||||
struct get_coordinate_type_for_rectangles {
|
||||
typedef typename polygon_traits<T>::coordinate_type type;
|
||||
};
|
||||
template <typename T>
|
||||
struct get_coordinate_type_for_rectangles<T, rectangle_concept> {
|
||||
typedef typename rectangle_traits<T>::coordinate_type type;
|
||||
};
|
||||
|
||||
template <typename output_container, typename iterator_type, typename rectangle_concept>
|
||||
void form_rectangles(output_container& output, iterator_type begin, iterator_type end,
|
||||
orientation_2d orient, rectangle_concept ) {
|
||||
typedef typename output_container::value_type rectangle_type;
|
||||
typedef typename get_coordinate_type_for_rectangles<rectangle_type, typename geometry_concept<rectangle_type>::type>::type Unit;
|
||||
rectangle_data<Unit> model;
|
||||
Unit prevPos = (std::numeric_limits<Unit>::max)();
|
||||
rectangle_formation::ScanLineToRects<rectangle_data<Unit> > scanlineToRects(orient, model);
|
||||
for(iterator_type itr = begin;
|
||||
itr != end; ++ itr) {
|
||||
Unit pos = (*itr).first;
|
||||
if(pos != prevPos) {
|
||||
scanlineToRects.nextMajorCoordinate(pos);
|
||||
prevPos = pos;
|
||||
}
|
||||
Unit lowy = (*itr).second.first;
|
||||
iterator_type tmp_itr = itr;
|
||||
++itr;
|
||||
Unit highy = (*itr).second.first;
|
||||
scanlineToRects.processEdge(output, interval_data<Unit>(lowy, highy));
|
||||
if(abs((*itr).second.second) > 1) itr = tmp_itr; //next edge begins from this vertex
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue