diff options
Diffstat (limited to 'source/blender/freestyle/intern/stroke/Operators.cpp')
-rw-r--r-- | source/blender/freestyle/intern/stroke/Operators.cpp | 2260 |
1 files changed, 1137 insertions, 1123 deletions
diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp index e9f6ff02f77..2c8a83e2518 100644 --- a/source/blender/freestyle/intern/stroke/Operators.cpp +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -37,1228 +37,1242 @@ Operators::I1DContainer Operators::_current_chains_set; Operators::I1DContainer *Operators::_current_set = NULL; Operators::StrokesContainer Operators::_current_strokes_set; -int Operators::select(UnaryPredicate1D& pred) +int Operators::select(UnaryPredicate1D &pred) { - if (!_current_set) - return 0; - if (_current_set->empty()) - return 0; - I1DContainer new_set; - I1DContainer rejected; - Functions1D::ChainingTimeStampF1D cts; - Functions1D::TimeStampF1D ts; - I1DContainer::iterator it = _current_set->begin(); - I1DContainer::iterator itbegin = it; - while (it != _current_set->end()) { - Interface1D *i1d = *it; - cts(*i1d); // mark everyone's chaining time stamp anyway - if (pred(*i1d) < 0) { - new_set.clear(); - rejected.clear(); - return -1; - } - if (pred.result) { - new_set.push_back(i1d); - ts(*i1d); - } - else { - rejected.push_back(i1d); - } - ++it; - } - if ((*itbegin)->getExactTypeName() != "ViewEdge") { - for (it = rejected.begin(); it != rejected.end(); ++it) - delete *it; - } - rejected.clear(); - _current_set->clear(); - *_current_set = new_set; - return 0; + if (!_current_set) + return 0; + if (_current_set->empty()) + return 0; + I1DContainer new_set; + I1DContainer rejected; + Functions1D::ChainingTimeStampF1D cts; + Functions1D::TimeStampF1D ts; + I1DContainer::iterator it = _current_set->begin(); + I1DContainer::iterator itbegin = it; + while (it != _current_set->end()) { + Interface1D *i1d = *it; + cts(*i1d); // mark everyone's chaining time stamp anyway + if (pred(*i1d) < 0) { + new_set.clear(); + rejected.clear(); + return -1; + } + if (pred.result) { + new_set.push_back(i1d); + ts(*i1d); + } + else { + rejected.push_back(i1d); + } + ++it; + } + if ((*itbegin)->getExactTypeName() != "ViewEdge") { + for (it = rejected.begin(); it != rejected.end(); ++it) + delete *it; + } + rejected.clear(); + _current_set->clear(); + *_current_set = new_set; + return 0; } -int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier) +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator &it, + UnaryPredicate1D &pred, + UnaryFunction1D_void &modifier) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - ViewEdge *edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) - { - if (pred(**it_edge) < 0) - goto error; - if (pred.result) - continue; - - edge = dynamic_cast<ViewEdge*>(*it_edge); - it.setBegin(edge); - it.setCurrentEdge(edge); - - Chain *new_chain = new Chain(id); - ++id; - while (true) { - new_chain->push_viewedge_back(*it, it.getOrientation()); - if (modifier(**it) < 0) { - delete new_chain; - goto error; - } - ++it; - if (it.isEnd()) - break; - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); - } - new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred(**it_edge) < 0) + goto error; + if (pred.result) + continue; + + edge = dynamic_cast<ViewEdge *>(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; + while (true) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + if (modifier(**it) < 0) { + delete new_chain; + goto error; + } + ++it; + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; + } + return 0; error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + delete (*it); + } + new_chains_set.clear(); + return -1; } -int Operators::chain(ViewEdgeInternal::ViewEdgeIterator& it, UnaryPredicate1D& pred) +int Operators::chain(ViewEdgeInternal::ViewEdgeIterator &it, UnaryPredicate1D &pred) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); - ViewEdge *edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) - { - if (pred(**it_edge) < 0) - goto error; - if (pred.result) - continue; - if (pred_ts(**it_edge) < 0) - goto error; - if (pred_ts.result) - continue; - - edge = dynamic_cast<ViewEdge*>(*it_edge); - it.setBegin(edge); - it.setCurrentEdge(edge); - - Chain *new_chain = new Chain(id); - ++id; - while (true) { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - ++it; - if (it.isEnd()) - break; - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - if (pred_ts(**it) < 0) { - delete new_chain; - goto error; - } - if (pred_ts.result) - break; - } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); - } - new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred(**it_edge) < 0) + goto error; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + goto error; + if (pred_ts.result) + continue; + + edge = dynamic_cast<ViewEdge *>(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; + while (true) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + ++it; + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + if (pred_ts(**it) < 0) { + delete new_chain; + goto error; + } + if (pred_ts.result) + break; + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; + } + return 0; error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + delete (*it); + } + new_chains_set.clear(); + return -1; } - #if 0 void Operators::bidirectionalChain(ViewEdgeIterator& it, UnaryPredicate1D& pred, UnaryFunction1D_void& modifier) { - if (_current_view_edges_set.empty()) - return; - - unsigned id = 0; - ViewEdge *edge; - Chain *new_chain; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) - { - if (pred(**it_edge)) - continue; - - edge = dynamic_cast<ViewEdge*>(*it_edge); - it.setBegin(edge); - it.setCurrentEdge(edge); - - Chain *new_chain = new Chain(id); - ++id; -#if 0 // FIXME - ViewEdgeIterator it_back(it); - --it_back; -#endif - do { - new_chain->push_viewedge_back(*it, it.getOrientation()); - modifier(**it); - ++it; - } while (!it.isEnd() && !pred(**it)); - it.setBegin(edge); - it.setCurrentEdge(edge); - --it; - while (!it.isEnd() && !pred(**it)) { - new_chain->push_viewedge_front(*it, it.getOrientation()); - modifier(**it); - --it; - } - - _current_chains_set.push_back(new_chain); - } - - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; + if (_current_view_edges_set.empty()) + return; + + unsigned id = 0; + ViewEdge *edge; + Chain *new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge)) + continue; + + edge = dynamic_cast<ViewEdge*>(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; +# if 0 // FIXME + ViewEdgeIterator it_back(it); + --it_back; +# endif + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + modifier(**it); + ++it; + } while (!it.isEnd() && !pred(**it)); + it.setBegin(edge); + it.setCurrentEdge(edge); + --it; + while (!it.isEnd() && !pred(**it)) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + modifier(**it); + --it; + } + + _current_chains_set.push_back(new_chain); + } + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; } void Operators::bidirectionalChain(ViewEdgeIterator& it, UnaryPredicate1D& pred) { - if (_current_view_edges_set.empty()) - return; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); - - ViewEdge *edge; - Chain *new_chain; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) - { - if (pred(**it_edge) || pred_ts(**it_edge)) - continue; - - edge = dynamic_cast<ViewEdge*>(*it_edge); - it.setBegin(edge); - it.setCurrentEdge(edge); - - Chain *new_chain = new Chain(id); - ++id; -#if 0 //FIXME - ViewEdgeIterator it_back(it); - --it_back; -#endif - do { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - ++it; - } while (!it.isEnd() && !pred(**it) && !pred_ts(**it)); - it.setBegin(edge); - it.setCurrentEdge(edge); - --it; - while (!it.isEnd() && !pred(**it) && !pred_ts(**it)) { - new_chain->push_viewedge_front(*it, it.getOrientation()); - ts(**it); - --it; - } - - _current_chains_set.push_back(new_chain); - } - - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; + if (_current_view_edges_set.empty()) + return; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + + ViewEdge *edge; + Chain *new_chain; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) + { + if (pred(**it_edge) || pred_ts(**it_edge)) + continue; + + edge = dynamic_cast<ViewEdge*>(*it_edge); + it.setBegin(edge); + it.setCurrentEdge(edge); + + Chain *new_chain = new Chain(id); + ++id; +# if 0 //FIXME + ViewEdgeIterator it_back(it); + --it_back; +# endif + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + ++it; + } while (!it.isEnd() && !pred(**it) && !pred_ts(**it)); + it.setBegin(edge); + it.setCurrentEdge(edge); + --it; + while (!it.isEnd() && !pred(**it) && !pred_ts(**it)) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + --it; + } + + _current_chains_set.push_back(new_chain); + } + + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; } #endif -int Operators::bidirectionalChain(ChainingIterator& it, UnaryPredicate1D& pred) +int Operators::bidirectionalChain(ChainingIterator &it, UnaryPredicate1D &pred) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); - ViewEdge *edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) - { - if (pred(**it_edge) < 0) - goto error; - if (pred.result) - continue; - if (pred_ts(**it_edge) < 0) - goto error; - if (pred_ts.result) - continue; - - edge = dynamic_cast<ViewEdge*>(*it_edge); - // re-init iterator - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.init() < 0) - goto error; - - Chain *new_chain = new Chain(id); - ++id; + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred(**it_edge) < 0) + goto error; + if (pred.result) + continue; + if (pred_ts(**it_edge) < 0) + goto error; + if (pred_ts.result) + continue; + + edge = dynamic_cast<ViewEdge *>(*it_edge); + // re-init iterator + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.init() < 0) + goto error; + + Chain *new_chain = new Chain(id); + ++id; #if 0 // FIXME - ViewEdgeIterator it_back(it); - --it_back; + ViewEdgeIterator it_back(it); + --it_back; #endif - while (true) { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - if (it.increment() < 0) { - delete new_chain; - goto error; - } - if (it.isEnd()) - break; - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - } - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.decrement() < 0) { - delete new_chain; - goto error; - } - while (!it.isEnd()) { - if (pred(**it) < 0) { - delete new_chain; - goto error; - } - if (pred.result) - break; - new_chain->push_viewedge_front(*it, it.getOrientation()); - ts(**it); - if (it.decrement() < 0) { - delete new_chain; - goto error; - } - } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); - } - new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; + while (true) { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + if (it.increment() < 0) { + delete new_chain; + goto error; + } + if (it.isEnd()) + break; + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + } + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.decrement() < 0) { + delete new_chain; + goto error; + } + while (!it.isEnd()) { + if (pred(**it) < 0) { + delete new_chain; + goto error; + } + if (pred.result) + break; + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + if (it.decrement() < 0) { + delete new_chain; + goto error; + } + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; + } + return 0; error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + delete (*it); + } + new_chains_set.clear(); + return -1; } -int Operators::bidirectionalChain(ChainingIterator& it) +int Operators::bidirectionalChain(ChainingIterator &it) { - if (_current_view_edges_set.empty()) - return 0; - - unsigned id = 0; - Functions1D::IncrementChainingTimeStampF1D ts; - Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); - ViewEdge *edge; - I1DContainer new_chains_set; - - for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); - it_edge != _current_view_edges_set.end(); - ++it_edge) - { - if (pred_ts(**it_edge) < 0) - goto error; - if (pred_ts.result) - continue; - - edge = dynamic_cast<ViewEdge*>(*it_edge); - // re-init iterator - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.init() < 0) - goto error; - - Chain *new_chain = new Chain(id); - ++id; + if (_current_view_edges_set.empty()) + return 0; + + unsigned id = 0; + Functions1D::IncrementChainingTimeStampF1D ts; + Predicates1D::EqualToChainingTimeStampUP1D pred_ts(TimeStamp::instance()->getTimeStamp() + 1); + ViewEdge *edge; + I1DContainer new_chains_set; + + for (I1DContainer::iterator it_edge = _current_view_edges_set.begin(); + it_edge != _current_view_edges_set.end(); + ++it_edge) { + if (pred_ts(**it_edge) < 0) + goto error; + if (pred_ts.result) + continue; + + edge = dynamic_cast<ViewEdge *>(*it_edge); + // re-init iterator + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.init() < 0) + goto error; + + Chain *new_chain = new Chain(id); + ++id; #if 0 // FIXME - ViewEdgeIterator it_back(it); - --it_back; + ViewEdgeIterator it_back(it); + --it_back; #endif - do { - new_chain->push_viewedge_back(*it, it.getOrientation()); - ts(**it); - if (it.increment() < 0) { // FIXME - delete new_chain; - goto error; - } - } while (!it.isEnd()); - it.setBegin(edge); - it.setCurrentEdge(edge); - it.setOrientation(true); - if (it.decrement() < 0) { // FIXME - delete new_chain; - goto error; - } - while (!it.isEnd()) { - new_chain->push_viewedge_front(*it, it.getOrientation()); - ts(**it); - if (it.decrement() < 0) { // FIXME - delete new_chain; - goto error; - } - } - new_chains_set.push_back(new_chain); - } - - if (!new_chains_set.empty()) { - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - _current_chains_set.push_back(*it); - } - new_chains_set.clear(); - _current_set = &_current_chains_set; - } - return 0; + do { + new_chain->push_viewedge_back(*it, it.getOrientation()); + ts(**it); + if (it.increment() < 0) { // FIXME + delete new_chain; + goto error; + } + } while (!it.isEnd()); + it.setBegin(edge); + it.setCurrentEdge(edge); + it.setOrientation(true); + if (it.decrement() < 0) { // FIXME + delete new_chain; + goto error; + } + while (!it.isEnd()) { + new_chain->push_viewedge_front(*it, it.getOrientation()); + ts(**it); + if (it.decrement() < 0) { // FIXME + delete new_chain; + goto error; + } + } + new_chains_set.push_back(new_chain); + } + + if (!new_chains_set.empty()) { + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + _current_chains_set.push_back(*it); + } + new_chains_set.clear(); + _current_set = &_current_chains_set; + } + return 0; error: - for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { - delete (*it); - } - new_chains_set.clear(); - return -1; + for (I1DContainer::iterator it = new_chains_set.begin(); it != new_chains_set.end(); ++it) { + delete (*it); + } + new_chains_set.clear(); + return -1; } -int Operators::sequentialSplit(UnaryPredicate0D& pred, float sampling) +int Operators::sequentialSplit(UnaryPredicate0D &pred, float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - CurvePoint *point; - Chain *new_curve; - I1DContainer splitted_chains; - Interface0DIterator first; - Interface0DIterator end; - Interface0DIterator last; - Interface0DIterator it; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; cit != citend; ++cit) { - Id currentId = (*cit)->getId(); - new_curve = new Chain(currentId); - first = (*cit)->pointsBegin(sampling); - end = (*cit)->pointsEnd(sampling); - last = end; - --last; - it = first; - - point = dynamic_cast<CurvePoint*>(&(*it)); - new_curve->push_vertex_back(point); - ++it; - for (; it != end; ++it) { - point = dynamic_cast<CurvePoint*>(&(*it)); - new_curve->push_vertex_back(point); - if (pred(it) < 0) { - delete new_curve; - goto error; - } - if (pred.result && (it != last)) { - splitted_chains.push_back(new_curve); - currentId.setSecond(currentId.getSecond() + 1); - new_curve = new Chain(currentId); - new_curve->push_vertex_back(point); - } - } - if (new_curve->nSegments() == 0) { - delete new_curve; - return 0; - } - - splitted_chains.push_back(new_curve); - } - - // Update the current set of chains: - cit = _current_chains_set.begin(); - for (; cit != citend; ++cit) { - delete (*cit); - } - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + CurvePoint *point; + Chain *new_curve; + I1DContainer splitted_chains; + Interface0DIterator first; + Interface0DIterator end; + Interface0DIterator last; + Interface0DIterator it; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + Id currentId = (*cit)->getId(); + new_curve = new Chain(currentId); + first = (*cit)->pointsBegin(sampling); + end = (*cit)->pointsEnd(sampling); + last = end; + --last; + it = first; + + point = dynamic_cast<CurvePoint *>(&(*it)); + new_curve->push_vertex_back(point); + ++it; + for (; it != end; ++it) { + point = dynamic_cast<CurvePoint *>(&(*it)); + new_curve->push_vertex_back(point); + if (pred(it) < 0) { + delete new_curve; + goto error; + } + if (pred.result && (it != last)) { + splitted_chains.push_back(new_curve); + currentId.setSecond(currentId.getSecond() + 1); + new_curve = new Chain(currentId); + new_curve->push_vertex_back(point); + } + } + if (new_curve->nSegments() == 0) { + delete new_curve; + return 0; + } + + splitted_chains.push_back(new_curve); + } + + // Update the current set of chains: + cit = _current_chains_set.begin(); + for (; cit != citend; ++cit) { + delete (*cit); + } + _current_chains_set.clear(); #if 0 - _current_chains_set = splitted_chains; + _current_chains_set = splitted_chains; #else - for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; - } - _current_chains_set.push_back(*cit); - } + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); + } #endif - splitted_chains.clear(); + splitted_chains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; error: - cit = splitted_chains.begin(); - citend = splitted_chains.end(); - for (; cit != citend; ++cit) { - delete (*cit); - } - splitted_chains.clear(); - return -1; + cit = splitted_chains.begin(); + citend = splitted_chains.end(); + for (; cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + return -1; } -int Operators::sequentialSplit(UnaryPredicate0D& startingPred, UnaryPredicate0D& stoppingPred, float sampling) +int Operators::sequentialSplit(UnaryPredicate0D &startingPred, + UnaryPredicate0D &stoppingPred, + float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - CurvePoint *point; - Chain *new_curve; - I1DContainer splitted_chains; - Interface0DIterator first; - Interface0DIterator end; - Interface0DIterator last; - Interface0DIterator itStart; - Interface0DIterator itStop; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; cit != citend; ++cit) { - Id currentId = (*cit)->getId(); - first = (*cit)->pointsBegin(sampling); - end = (*cit)->pointsEnd(sampling); - last = end; - --last; - itStart = first; - do { - itStop = itStart; - ++itStop; - - new_curve = new Chain(currentId); - currentId.setSecond(currentId.getSecond() + 1); - - point = dynamic_cast<CurvePoint*>(&(*itStart)); - new_curve->push_vertex_back(point); - do { - point = dynamic_cast<CurvePoint*>(&(*itStop)); - new_curve->push_vertex_back(point); - ++itStop; - if (itStop == end) - break; - if (stoppingPred(itStop) < 0) { - delete new_curve; - goto error; - } - } while (!stoppingPred.result); - if (itStop != end) { - point = dynamic_cast<CurvePoint*>(&(*itStop)); - new_curve->push_vertex_back(point); - } - if (new_curve->nSegments() == 0) { - delete new_curve; - } - else { - splitted_chains.push_back(new_curve); - } - // find next start - do { - ++itStart; - if (itStart == end) - break; - if (startingPred(itStart) < 0) - goto error; - } while (!startingPred.result); - } while ((itStart != end) && (itStart != last)); - } - - // Update the current set of chains: - cit = _current_chains_set.begin(); - for (; cit != citend; ++cit) { - delete (*cit); - } - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + CurvePoint *point; + Chain *new_curve; + I1DContainer splitted_chains; + Interface0DIterator first; + Interface0DIterator end; + Interface0DIterator last; + Interface0DIterator itStart; + Interface0DIterator itStop; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + Id currentId = (*cit)->getId(); + first = (*cit)->pointsBegin(sampling); + end = (*cit)->pointsEnd(sampling); + last = end; + --last; + itStart = first; + do { + itStop = itStart; + ++itStop; + + new_curve = new Chain(currentId); + currentId.setSecond(currentId.getSecond() + 1); + + point = dynamic_cast<CurvePoint *>(&(*itStart)); + new_curve->push_vertex_back(point); + do { + point = dynamic_cast<CurvePoint *>(&(*itStop)); + new_curve->push_vertex_back(point); + ++itStop; + if (itStop == end) + break; + if (stoppingPred(itStop) < 0) { + delete new_curve; + goto error; + } + } while (!stoppingPred.result); + if (itStop != end) { + point = dynamic_cast<CurvePoint *>(&(*itStop)); + new_curve->push_vertex_back(point); + } + if (new_curve->nSegments() == 0) { + delete new_curve; + } + else { + splitted_chains.push_back(new_curve); + } + // find next start + do { + ++itStart; + if (itStart == end) + break; + if (startingPred(itStart) < 0) + goto error; + } while (!startingPred.result); + } while ((itStart != end) && (itStart != last)); + } + + // Update the current set of chains: + cit = _current_chains_set.begin(); + for (; cit != citend; ++cit) { + delete (*cit); + } + _current_chains_set.clear(); #if 0 - _current_chains_set = splitted_chains; + _current_chains_set = splitted_chains; #else - for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; - } - _current_chains_set.push_back(*cit); - } + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); + } #endif - splitted_chains.clear(); + splitted_chains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; error: - cit = splitted_chains.begin(); - citend = splitted_chains.end(); - for (; cit != citend; ++cit) { - delete (*cit); - } - splitted_chains.clear(); - return -1; + cit = splitted_chains.begin(); + citend = splitted_chains.end(); + for (; cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + return -1; } // Internal function -static int __recursiveSplit(Chain *_curve, UnaryFunction0D<double>& func, UnaryPredicate1D& pred, float sampling, - Operators::I1DContainer& newChains, Operators::I1DContainer& splitted_chains) +static int __recursiveSplit(Chain *_curve, + UnaryFunction0D<double> &func, + UnaryPredicate1D &pred, + float sampling, + Operators::I1DContainer &newChains, + Operators::I1DContainer &splitted_chains) { - if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) { - newChains.push_back(_curve); - return 0; - } - - CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); - CurveInternal::CurvePointIterator second = first; - ++second; - CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); - CurveInternal::CurvePointIterator it = second; - CurveInternal::CurvePointIterator split = second; - Interface0DIterator it0d = it.castToInterface0DIterator(); - real _min = FLT_MAX; // func(it0d); - ++it; - CurveInternal::CurvePointIterator next = it; - ++next; - - bool bsplit = false; - for (; ((it != end) && (next != end)); ++it, ++next) { - it0d = it.castToInterface0DIterator(); - if (func(it0d) < 0) - return -1; - if (func.result < _min) { - _min = func.result; - split = it; - bsplit = true; - } - } - - if (!bsplit) { // we didn't find any minimum - newChains.push_back(_curve); - return 0; - } - - // retrieves the current splitting id - Id *newId = _curve->getSplittingId(); - if (newId == 0) { - newId = new Id(_curve->getId()); - _curve->setSplittingId(newId); - } - - Chain *new_curve_a = new Chain(*newId); - newId->setSecond(newId->getSecond() + 1); - new_curve_a->setSplittingId(newId); - Chain *new_curve_b = new Chain(*newId); - newId->setSecond(newId->getSecond() + 1); - new_curve_b->setSplittingId(newId); - - CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend = _curve->curveVerticesEnd(); - CurveInternal::CurvePointIterator vnext = vit; - ++vnext; - - for (; (vit != vitend) && (vnext != vitend) && (vnext._CurvilinearLength < split._CurvilinearLength); - ++vit, ++vnext) - { - new_curve_a->push_vertex_back(&(*vit)); - } - if ((vit == vitend) || (vnext == vitend)) { - if (G.debug & G_DEBUG_FREESTYLE) { - cout << "The split takes place in bad location" << endl; - } - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - - // build the two resulting chains - new_curve_a->push_vertex_back(&(*vit)); - new_curve_a->push_vertex_back(&(*split)); - new_curve_b->push_vertex_back(&(*split)); - - for (vit = vnext; vit != vitend; ++vit) - new_curve_b->push_vertex_back(&(*vit)); - - // let's check whether one or two of the two new curves satisfy the stopping condition or not. - // (if one of them satisfies it, we don't split) - if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { - delete new_curve_a; - delete new_curve_b; - return -1; - } - if (pred.result) { - // we don't actually create these two chains - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - // here we know we'll split _curve: - splitted_chains.push_back(_curve); - - __recursiveSplit(new_curve_a, func, pred, sampling, newChains, splitted_chains); - __recursiveSplit(new_curve_b, func, pred, sampling, newChains, splitted_chains); - return 0; + if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) { + newChains.push_back(_curve); + return 0; + } + + CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); + CurveInternal::CurvePointIterator second = first; + ++second; + CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); + CurveInternal::CurvePointIterator it = second; + CurveInternal::CurvePointIterator split = second; + Interface0DIterator it0d = it.castToInterface0DIterator(); + real _min = FLT_MAX; // func(it0d); + ++it; + CurveInternal::CurvePointIterator next = it; + ++next; + + bool bsplit = false; + for (; ((it != end) && (next != end)); ++it, ++next) { + it0d = it.castToInterface0DIterator(); + if (func(it0d) < 0) + return -1; + if (func.result < _min) { + _min = func.result; + split = it; + bsplit = true; + } + } + + if (!bsplit) { // we didn't find any minimum + newChains.push_back(_curve); + return 0; + } + + // retrieves the current splitting id + Id *newId = _curve->getSplittingId(); + if (newId == 0) { + newId = new Id(_curve->getId()); + _curve->setSplittingId(newId); + } + + Chain *new_curve_a = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_a->setSplittingId(newId); + Chain *new_curve_b = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_b->setSplittingId(newId); + + CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), + vitend = _curve->curveVerticesEnd(); + CurveInternal::CurvePointIterator vnext = vit; + ++vnext; + + for (; (vit != vitend) && (vnext != vitend) && + (vnext._CurvilinearLength < split._CurvilinearLength); + ++vit, ++vnext) { + new_curve_a->push_vertex_back(&(*vit)); + } + if ((vit == vitend) || (vnext == vitend)) { + if (G.debug & G_DEBUG_FREESTYLE) { + cout << "The split takes place in bad location" << endl; + } + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + + // build the two resulting chains + new_curve_a->push_vertex_back(&(*vit)); + new_curve_a->push_vertex_back(&(*split)); + new_curve_b->push_vertex_back(&(*split)); + + for (vit = vnext; vit != vitend; ++vit) + new_curve_b->push_vertex_back(&(*vit)); + + // let's check whether one or two of the two new curves satisfy the stopping condition or not. + // (if one of them satisfies it, we don't split) + if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { + delete new_curve_a; + delete new_curve_b; + return -1; + } + if (pred.result) { + // we don't actually create these two chains + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + // here we know we'll split _curve: + splitted_chains.push_back(_curve); + + __recursiveSplit(new_curve_a, func, pred, sampling, newChains, splitted_chains); + __recursiveSplit(new_curve_b, func, pred, sampling, newChains, splitted_chains); + return 0; } -int Operators::recursiveSplit(UnaryFunction0D<double>& func, UnaryPredicate1D& pred, float sampling) +int Operators::recursiveSplit(UnaryFunction0D<double> &func, + UnaryPredicate1D &pred, + float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - - Chain *currentChain = 0; - I1DContainer splitted_chains; - I1DContainer newChains; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; cit != citend; ++cit) { - currentChain = dynamic_cast<Chain*>(*cit); - if (!currentChain) - continue; - // let's check the first one: - if (pred(*currentChain) < 0) - return -1; - if (!pred.result) { - __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains); - } - else { - newChains.push_back(currentChain); - } - } - // Update the current set of chains: - if (!splitted_chains.empty()) { - for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { - delete (*cit); - } - splitted_chains.clear(); - } - - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + + Chain *currentChain = 0; + I1DContainer splitted_chains; + I1DContainer newChains; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + currentChain = dynamic_cast<Chain *>(*cit); + if (!currentChain) + continue; + // let's check the first one: + if (pred(*currentChain) < 0) + return -1; + if (!pred.result) { + __recursiveSplit(currentChain, func, pred, sampling, newChains, splitted_chains); + } + else { + newChains.push_back(currentChain); + } + } + // Update the current set of chains: + if (!splitted_chains.empty()) { + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + } + + _current_chains_set.clear(); #if 0 - _current_chains_set = newChains; + _current_chains_set = newChains; #else - for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; - } - _current_chains_set.push_back(*cit); - } + for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); + } #endif - newChains.clear(); + newChains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; } // recursive split with pred 0D -static int __recursiveSplit(Chain *_curve, UnaryFunction0D<double>& func, UnaryPredicate0D& pred0d, - UnaryPredicate1D& pred, float sampling, - Operators::I1DContainer& newChains, Operators::I1DContainer& splitted_chains) +static int __recursiveSplit(Chain *_curve, + UnaryFunction0D<double> &func, + UnaryPredicate0D &pred0d, + UnaryPredicate1D &pred, + float sampling, + Operators::I1DContainer &newChains, + Operators::I1DContainer &splitted_chains) { - if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) { - newChains.push_back(_curve); - return 0; - } - - CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); - CurveInternal::CurvePointIterator second = first; - ++second; - CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); - CurveInternal::CurvePointIterator it = second; - CurveInternal::CurvePointIterator split = second; - Interface0DIterator it0d = it.castToInterface0DIterator(); + if (((_curve->nSegments() == 1) && (sampling == 0)) || (_curve->getLength2D() <= sampling)) { + newChains.push_back(_curve); + return 0; + } + + CurveInternal::CurvePointIterator first = _curve->curvePointsBegin(sampling); + CurveInternal::CurvePointIterator second = first; + ++second; + CurveInternal::CurvePointIterator end = _curve->curvePointsEnd(sampling); + CurveInternal::CurvePointIterator it = second; + CurveInternal::CurvePointIterator split = second; + Interface0DIterator it0d = it.castToInterface0DIterator(); #if 0 - real _min = func(it0d); - ++it; + real _min = func(it0d); + ++it; #endif - real _min = FLT_MAX; - ++it; - real mean = 0.f; - //soc unused - real variance = 0.0f; - unsigned count = 0; - CurveInternal::CurvePointIterator next = it; - ++next; - - bool bsplit = false; - for (; ((it != end) && (next != end)); ++it, ++next) { - ++count; - it0d = it.castToInterface0DIterator(); - if (pred0d(it0d) < 0) - return -1; - if (!pred0d.result) - continue; - if (func(it0d) < 0) - return -1; - mean += func.result; - if (func.result < _min) { - _min = func.result; - split = it; - bsplit = true; - } - } - mean /= (float)count; - - //if ((!bsplit) || (mean - _min > mean)) { // we didn't find any minimum - if (!bsplit) { // we didn't find any minimum - newChains.push_back(_curve); - return 0; - } - - // retrieves the current splitting id - Id *newId = _curve->getSplittingId(); - if (newId == NULL) { - newId = new Id(_curve->getId()); - _curve->setSplittingId(newId); - } - - Chain *new_curve_a = new Chain(*newId); - newId->setSecond(newId->getSecond() + 1); - new_curve_a->setSplittingId(newId); - Chain *new_curve_b = new Chain(*newId); - newId->setSecond(newId->getSecond() + 1); - new_curve_b->setSplittingId(newId); - - CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), vitend = _curve->curveVerticesEnd(); - CurveInternal::CurvePointIterator vnext = vit; - ++vnext; - - for (; - (vit != vitend) && (vnext != vitend) && (vnext._CurvilinearLength < split._CurvilinearLength); - ++vit, ++vnext) - { - new_curve_a->push_vertex_back(&(*vit)); - } - if ((vit == vitend) || (vnext == vitend)) { - if (G.debug & G_DEBUG_FREESTYLE) { - cout << "The split takes place in bad location" << endl; - } - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - - // build the two resulting chains - new_curve_a->push_vertex_back(&(*vit)); - new_curve_a->push_vertex_back(&(*split)); - new_curve_b->push_vertex_back(&(*split)); - - for (vit = vnext; vit != vitend; ++vit) - new_curve_b->push_vertex_back(&(*vit)); - - // let's check whether one or two of the two new curves satisfy the stopping condition or not. - // (if one of them satisfies it, we don't split) - if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { - delete new_curve_a; - delete new_curve_b; - return -1; - } - if (pred.result) { - // we don't actually create these two chains - newChains.push_back(_curve); - delete new_curve_a; - delete new_curve_b; - return 0; - } - // here we know we'll split _curve: - splitted_chains.push_back(_curve); - - __recursiveSplit(new_curve_a, func, pred0d, pred, sampling, newChains, splitted_chains); - __recursiveSplit(new_curve_b, func, pred0d, pred, sampling, newChains, splitted_chains); - return 0; + real _min = FLT_MAX; + ++it; + real mean = 0.f; + //soc unused - real variance = 0.0f; + unsigned count = 0; + CurveInternal::CurvePointIterator next = it; + ++next; + + bool bsplit = false; + for (; ((it != end) && (next != end)); ++it, ++next) { + ++count; + it0d = it.castToInterface0DIterator(); + if (pred0d(it0d) < 0) + return -1; + if (!pred0d.result) + continue; + if (func(it0d) < 0) + return -1; + mean += func.result; + if (func.result < _min) { + _min = func.result; + split = it; + bsplit = true; + } + } + mean /= (float)count; + + //if ((!bsplit) || (mean - _min > mean)) { // we didn't find any minimum + if (!bsplit) { // we didn't find any minimum + newChains.push_back(_curve); + return 0; + } + + // retrieves the current splitting id + Id *newId = _curve->getSplittingId(); + if (newId == NULL) { + newId = new Id(_curve->getId()); + _curve->setSplittingId(newId); + } + + Chain *new_curve_a = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_a->setSplittingId(newId); + Chain *new_curve_b = new Chain(*newId); + newId->setSecond(newId->getSecond() + 1); + new_curve_b->setSplittingId(newId); + + CurveInternal::CurvePointIterator vit = _curve->curveVerticesBegin(), + vitend = _curve->curveVerticesEnd(); + CurveInternal::CurvePointIterator vnext = vit; + ++vnext; + + for (; (vit != vitend) && (vnext != vitend) && + (vnext._CurvilinearLength < split._CurvilinearLength); + ++vit, ++vnext) { + new_curve_a->push_vertex_back(&(*vit)); + } + if ((vit == vitend) || (vnext == vitend)) { + if (G.debug & G_DEBUG_FREESTYLE) { + cout << "The split takes place in bad location" << endl; + } + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + + // build the two resulting chains + new_curve_a->push_vertex_back(&(*vit)); + new_curve_a->push_vertex_back(&(*split)); + new_curve_b->push_vertex_back(&(*split)); + + for (vit = vnext; vit != vitend; ++vit) + new_curve_b->push_vertex_back(&(*vit)); + + // let's check whether one or two of the two new curves satisfy the stopping condition or not. + // (if one of them satisfies it, we don't split) + if (pred(*new_curve_a) < 0 || (!pred.result && pred(*new_curve_b) < 0)) { + delete new_curve_a; + delete new_curve_b; + return -1; + } + if (pred.result) { + // we don't actually create these two chains + newChains.push_back(_curve); + delete new_curve_a; + delete new_curve_b; + return 0; + } + // here we know we'll split _curve: + splitted_chains.push_back(_curve); + + __recursiveSplit(new_curve_a, func, pred0d, pred, sampling, newChains, splitted_chains); + __recursiveSplit(new_curve_b, func, pred0d, pred, sampling, newChains, splitted_chains); + return 0; } -int Operators::recursiveSplit(UnaryFunction0D<double>& func, UnaryPredicate0D& pred0d, UnaryPredicate1D& pred, +int Operators::recursiveSplit(UnaryFunction0D<double> &func, + UnaryPredicate0D &pred0d, + UnaryPredicate1D &pred, float sampling) { - if (_current_chains_set.empty()) { - cerr << "Warning: current set empty" << endl; - return 0; - } - - Chain *currentChain = 0; - I1DContainer splitted_chains; - I1DContainer newChains; - I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); - for (; cit != citend; ++cit) { - currentChain = dynamic_cast<Chain*>(*cit); - if (!currentChain) - continue; - // let's check the first one: - if (pred(*currentChain) < 0) - return -1; - if (!pred.result) { - __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains); - } - else { - newChains.push_back(currentChain); - } - } - // Update the current set of chains: - if (!splitted_chains.empty()) { - for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { - delete (*cit); - } - splitted_chains.clear(); - } - - _current_chains_set.clear(); + if (_current_chains_set.empty()) { + cerr << "Warning: current set empty" << endl; + return 0; + } + + Chain *currentChain = 0; + I1DContainer splitted_chains; + I1DContainer newChains; + I1DContainer::iterator cit = _current_chains_set.begin(), citend = _current_chains_set.end(); + for (; cit != citend; ++cit) { + currentChain = dynamic_cast<Chain *>(*cit); + if (!currentChain) + continue; + // let's check the first one: + if (pred(*currentChain) < 0) + return -1; + if (!pred.result) { + __recursiveSplit(currentChain, func, pred0d, pred, sampling, newChains, splitted_chains); + } + else { + newChains.push_back(currentChain); + } + } + // Update the current set of chains: + if (!splitted_chains.empty()) { + for (cit = splitted_chains.begin(), citend = splitted_chains.end(); cit != citend; ++cit) { + delete (*cit); + } + splitted_chains.clear(); + } + + _current_chains_set.clear(); #if 0 - _current_chains_set = newChains; + _current_chains_set = newChains; #else - for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) { - if ((*cit)->getLength2D() < M_EPSILON) { - delete (*cit); - continue; - } - _current_chains_set.push_back(*cit); - } + for (cit = newChains.begin(), citend = newChains.end(); cit != citend; ++cit) { + if ((*cit)->getLength2D() < M_EPSILON) { + delete (*cit); + continue; + } + _current_chains_set.push_back(*cit); + } #endif - newChains.clear(); + newChains.clear(); - if (!_current_chains_set.empty()) - _current_set = &_current_chains_set; - return 0; + if (!_current_chains_set.empty()) + _current_set = &_current_chains_set; + return 0; } // Internal class -class PredicateWrapper -{ -public: - inline PredicateWrapper(BinaryPredicate1D& pred) - { - _pred = &pred; - } - - inline bool operator()(Interface1D *i1, Interface1D *i2) - { - if (i1 == i2) - return false; - if ((*_pred)(*i1, *i2) < 0) - throw std::runtime_error("comparison failed"); - return _pred->result; - } - -private: - BinaryPredicate1D *_pred; +class PredicateWrapper { + public: + inline PredicateWrapper(BinaryPredicate1D &pred) + { + _pred = &pred; + } + + inline bool operator()(Interface1D *i1, Interface1D *i2) + { + if (i1 == i2) + return false; + if ((*_pred)(*i1, *i2) < 0) + throw std::runtime_error("comparison failed"); + return _pred->result; + } + + private: + BinaryPredicate1D *_pred; }; -int Operators::sort(BinaryPredicate1D& pred) +int Operators::sort(BinaryPredicate1D &pred) { - if (!_current_set) - return 0; - PredicateWrapper wrapper(pred); - try { - std::sort(_current_set->begin(), _current_set->end(), wrapper); - } - catch (std::runtime_error &e) { - cerr << "Warning: Operator.sort(): " << e.what() << endl; - return -1; - } - return 0; + if (!_current_set) + return 0; + PredicateWrapper wrapper(pred); + try { + std::sort(_current_set->begin(), _current_set->end(), wrapper); + } + catch (std::runtime_error &e) { + cerr << "Warning: Operator.sort(): " << e.what() << endl; + return -1; + } + return 0; } -static Stroke *createStroke(Interface1D& inter) +static Stroke *createStroke(Interface1D &inter) { - Stroke *stroke = new Stroke; - stroke->setId(inter.getId()); - - float currentCurvilignAbscissa = 0.0f; - - Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); - Interface0DIterator itfirst = it; - - Vec2r current(it->getPoint2D()); - Vec2r previous = current; - SVertex *sv; - CurvePoint *cp; - StrokeVertex *stroke_vertex = NULL; - bool hasSingularity = false; - - do { - cp = dynamic_cast<CurvePoint*>(&(*it)); - if (!cp) { - sv = dynamic_cast<SVertex*>(&(*it)); - if (!sv) { - cerr << "Warning: unexpected Vertex type" << endl; - continue; - } - stroke_vertex = new StrokeVertex(sv); - } - else { - stroke_vertex = new StrokeVertex(cp); - } - current = stroke_vertex->getPoint2D(); - Vec2r vec_tmp(current - previous); - real dist = vec_tmp.norm(); - if (dist < 1.0e-6) - hasSingularity = true; - currentCurvilignAbscissa += dist; - stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); - stroke->push_back(stroke_vertex); - previous = current; - ++it; - } while ((it != itend) && (it != itfirst)); - - if (it == itfirst) { - // Add last vertex: - cp = dynamic_cast<CurvePoint*>(&(*it)); - if (!cp) { - sv = dynamic_cast<SVertex*>(&(*it)); - if (!sv) - cerr << "Warning: unexpected Vertex type" << endl; - else - stroke_vertex = new StrokeVertex(sv); - } - else { - stroke_vertex = new StrokeVertex(cp); - } - current = stroke_vertex->getPoint2D(); - Vec2r vec_tmp(current - previous); - real dist = vec_tmp.norm(); - if (dist < 1.0e-6) - hasSingularity = true; - currentCurvilignAbscissa += dist; - stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); - stroke->push_back(stroke_vertex); - } - // Discard the stroke if the number of stroke vertices is less than two - if (stroke->strokeVerticesSize() < 2) { - delete stroke; - return NULL; - } - stroke->setLength(currentCurvilignAbscissa); - if (hasSingularity) { - // Try to address singular points such that the distance between two subsequent vertices - // are smaller than epsilon. - StrokeInternal::StrokeVertexIterator v = stroke->strokeVerticesBegin(); - StrokeInternal::StrokeVertexIterator vnext = v; - ++vnext; - Vec2r next((*v).getPoint()); - while (!vnext.isEnd()) { - current = next; - next = (*vnext).getPoint(); - if ((next - current).norm() < 1.0e-6) { - StrokeInternal::StrokeVertexIterator vprevious = v; - if (!vprevious.isBegin()) - --vprevious; - - // collect a set of overlapping vertices - std::vector<StrokeVertex *> overlapping_vertices; - overlapping_vertices.push_back(&(*v)); - do { - overlapping_vertices.push_back(&(*vnext)); - current = next; - ++v; - ++vnext; - if (vnext.isEnd()) - break; - next = (*vnext).getPoint(); - } while ((next - current).norm() < 1.0e-6); - - Vec2r target; - bool reverse; - if (!vnext.isEnd()) { - target = (*vnext).getPoint(); - reverse = false; - } - else if (!vprevious.isBegin()) { - target = (*vprevious).getPoint(); - reverse = true; - } - else { - // Discard the stroke because all stroke vertices are overlapping - delete stroke; - return NULL; - } - current = overlapping_vertices.front()->getPoint(); - Vec2r dir(target - current); - real dist = dir.norm(); - real len = 1.0e-3; // default offset length - int nvert = overlapping_vertices.size(); - if (dist < len * nvert) { - len = dist / nvert; - } - dir.normalize(); - Vec2r offset(dir * len); - // add the offset to the overlapping vertices - StrokeVertex *sv; - std::vector<StrokeVertex *>::iterator it = overlapping_vertices.begin(); - if (!reverse) { - for (int n = 0; n < nvert; n++) { - sv = (*it); - sv->setPoint(sv->getPoint() + offset * (n + 1)); - ++it; - } - } - else { - for (int n = 0; n < nvert; n++) { - sv = (*it); - sv->setPoint(sv->getPoint() + offset * (nvert - n)); - ++it; - } - } - - if (vnext.isEnd()) - break; - } - ++v; - ++vnext; - } - } - { - // Check if the stroke no longer contains singular points - Interface0DIterator v = stroke->verticesBegin(); - Interface0DIterator vnext = v; - ++vnext; - Vec2r next((*v).getPoint2D()); - bool warning = false; - while (!vnext.isEnd()) { - current = next; - next = (*vnext).getPoint2D(); - if ((next - current).norm() < 1.0e-6) { - warning = true; - break; - } - ++v; - ++vnext; - } - if (warning && G.debug & G_DEBUG_FREESTYLE) { - printf("Warning: stroke contains singular points.\n"); - } - } - return stroke; + Stroke *stroke = new Stroke; + stroke->setId(inter.getId()); + + float currentCurvilignAbscissa = 0.0f; + + Interface0DIterator it = inter.verticesBegin(), itend = inter.verticesEnd(); + Interface0DIterator itfirst = it; + + Vec2r current(it->getPoint2D()); + Vec2r previous = current; + SVertex *sv; + CurvePoint *cp; + StrokeVertex *stroke_vertex = NULL; + bool hasSingularity = false; + + do { + cp = dynamic_cast<CurvePoint *>(&(*it)); + if (!cp) { + sv = dynamic_cast<SVertex *>(&(*it)); + if (!sv) { + cerr << "Warning: unexpected Vertex type" << endl; + continue; + } + stroke_vertex = new StrokeVertex(sv); + } + else { + stroke_vertex = new StrokeVertex(cp); + } + current = stroke_vertex->getPoint2D(); + Vec2r vec_tmp(current - previous); + real dist = vec_tmp.norm(); + if (dist < 1.0e-6) + hasSingularity = true; + currentCurvilignAbscissa += dist; + stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); + stroke->push_back(stroke_vertex); + previous = current; + ++it; + } while ((it != itend) && (it != itfirst)); + + if (it == itfirst) { + // Add last vertex: + cp = dynamic_cast<CurvePoint *>(&(*it)); + if (!cp) { + sv = dynamic_cast<SVertex *>(&(*it)); + if (!sv) + cerr << "Warning: unexpected Vertex type" << endl; + else + stroke_vertex = new StrokeVertex(sv); + } + else { + stroke_vertex = new StrokeVertex(cp); + } + current = stroke_vertex->getPoint2D(); + Vec2r vec_tmp(current - previous); + real dist = vec_tmp.norm(); + if (dist < 1.0e-6) + hasSingularity = true; + currentCurvilignAbscissa += dist; + stroke_vertex->setCurvilinearAbscissa(currentCurvilignAbscissa); + stroke->push_back(stroke_vertex); + } + // Discard the stroke if the number of stroke vertices is less than two + if (stroke->strokeVerticesSize() < 2) { + delete stroke; + return NULL; + } + stroke->setLength(currentCurvilignAbscissa); + if (hasSingularity) { + // Try to address singular points such that the distance between two subsequent vertices + // are smaller than epsilon. + StrokeInternal::StrokeVertexIterator v = stroke->strokeVerticesBegin(); + StrokeInternal::StrokeVertexIterator vnext = v; + ++vnext; + Vec2r next((*v).getPoint()); + while (!vnext.isEnd()) { + current = next; + next = (*vnext).getPoint(); + if ((next - current).norm() < 1.0e-6) { + StrokeInternal::StrokeVertexIterator vprevious = v; + if (!vprevious.isBegin()) + --vprevious; + + // collect a set of overlapping vertices + std::vector<StrokeVertex *> overlapping_vertices; + overlapping_vertices.push_back(&(*v)); + do { + overlapping_vertices.push_back(&(*vnext)); + current = next; + ++v; + ++vnext; + if (vnext.isEnd()) + break; + next = (*vnext).getPoint(); + } while ((next - current).norm() < 1.0e-6); + + Vec2r target; + bool reverse; + if (!vnext.isEnd()) { + target = (*vnext).getPoint(); + reverse = false; + } + else if (!vprevious.isBegin()) { + target = (*vprevious).getPoint(); + reverse = true; + } + else { + // Discard the stroke because all stroke vertices are overlapping + delete stroke; + return NULL; + } + current = overlapping_vertices.front()->getPoint(); + Vec2r dir(target - current); + real dist = dir.norm(); + real len = 1.0e-3; // default offset length + int nvert = overlapping_vertices.size(); + if (dist < len * nvert) { + len = dist / nvert; + } + dir.normalize(); + Vec2r offset(dir * len); + // add the offset to the overlapping vertices + StrokeVertex *sv; + std::vector<StrokeVertex *>::iterator it = overlapping_vertices.begin(); + if (!reverse) { + for (int n = 0; n < nvert; n++) { + sv = (*it); + sv->setPoint(sv->getPoint() + offset * (n + 1)); + ++it; + } + } + else { + for (int n = 0; n < nvert; n++) { + sv = (*it); + sv->setPoint(sv->getPoint() + offset * (nvert - n)); + ++it; + } + } + + if (vnext.isEnd()) + break; + } + ++v; + ++vnext; + } + } + { + // Check if the stroke no longer contains singular points + Interface0DIterator v = stroke->verticesBegin(); + Interface0DIterator vnext = v; + ++vnext; + Vec2r next((*v).getPoint2D()); + bool warning = false; + while (!vnext.isEnd()) { + current = next; + next = (*vnext).getPoint2D(); + if ((next - current).norm() < 1.0e-6) { + warning = true; + break; + } + ++v; + ++vnext; + } + if (warning && G.debug & G_DEBUG_FREESTYLE) { + printf("Warning: stroke contains singular points.\n"); + } + } + return stroke; } - -inline int applyShading(Stroke& stroke, vector<StrokeShader*>& shaders) +inline int applyShading(Stroke &stroke, vector<StrokeShader *> &shaders) { - for (vector<StrokeShader*>::iterator it = shaders.begin(); it != shaders.end(); ++it) { - if ((*it)->shade(stroke) < 0) { - return -1; - } - } - return 0; + for (vector<StrokeShader *>::iterator it = shaders.begin(); it != shaders.end(); ++it) { + if ((*it)->shade(stroke) < 0) { + return -1; + } + } + return 0; } -int Operators::create(UnaryPredicate1D& pred, vector<StrokeShader*> shaders) +int Operators::create(UnaryPredicate1D &pred, vector<StrokeShader *> shaders) { - //Canvas* canvas = Canvas::getInstance(); - if (!_current_set) { - cerr << "Warning: current set empty" << endl; - return 0; - } - StrokesContainer new_strokes_set; - for (Operators::I1DContainer::iterator it = _current_set->begin(); it != _current_set->end(); ++it) { - if (pred(**it) < 0) - goto error; - if (!pred.result) - continue; - - Stroke *stroke = createStroke(**it); - if (stroke) { - if (applyShading(*stroke, shaders) < 0) { - delete stroke; - goto error; - } - //canvas->RenderStroke(stroke); - new_strokes_set.push_back(stroke); - } - } - - for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); ++it) { - _current_strokes_set.push_back(*it); - } - new_strokes_set.clear(); - return 0; + //Canvas* canvas = Canvas::getInstance(); + if (!_current_set) { + cerr << "Warning: current set empty" << endl; + return 0; + } + StrokesContainer new_strokes_set; + for (Operators::I1DContainer::iterator it = _current_set->begin(); it != _current_set->end(); + ++it) { + if (pred(**it) < 0) + goto error; + if (!pred.result) + continue; + + Stroke *stroke = createStroke(**it); + if (stroke) { + if (applyShading(*stroke, shaders) < 0) { + delete stroke; + goto error; + } + //canvas->RenderStroke(stroke); + new_strokes_set.push_back(stroke); + } + } + + for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); + ++it) { + _current_strokes_set.push_back(*it); + } + new_strokes_set.clear(); + return 0; error: - for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); ++it) { - delete (*it); - } - new_strokes_set.clear(); - return -1; + for (StrokesContainer::iterator it = new_strokes_set.begin(); it != new_strokes_set.end(); + ++it) { + delete (*it); + } + new_strokes_set.clear(); + return -1; } void Operators::reset(bool removeStrokes) { - ViewMap *vm = ViewMap::getInstance(); - if (!vm) { - cerr << "Error: no ViewMap computed yet" << endl; - return; - } - _current_view_edges_set.clear(); - for (I1DContainer::iterator it = _current_chains_set.begin(); it != _current_chains_set.end(); ++it) - delete *it; - _current_chains_set.clear(); - - ViewMap::viewedges_container& vedges = vm->ViewEdges(); - ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end(); - for (; ve != veend; ++ve) { - if ((*ve)->getLength2D() < M_EPSILON) - continue; - _current_view_edges_set.push_back(*ve); - } - _current_set = &_current_view_edges_set; - if (removeStrokes) - _current_strokes_set.clear(); + ViewMap *vm = ViewMap::getInstance(); + if (!vm) { + cerr << "Error: no ViewMap computed yet" << endl; + return; + } + _current_view_edges_set.clear(); + for (I1DContainer::iterator it = _current_chains_set.begin(); it != _current_chains_set.end(); + ++it) + delete *it; + _current_chains_set.clear(); + + ViewMap::viewedges_container &vedges = vm->ViewEdges(); + ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end(); + for (; ve != veend; ++ve) { + if ((*ve)->getLength2D() < M_EPSILON) + continue; + _current_view_edges_set.push_back(*ve); + } + _current_set = &_current_view_edges_set; + if (removeStrokes) + _current_strokes_set.clear(); } } /* namespace Freestyle */ |