// 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) { 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; #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; }
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 0 _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); } #endif splitted_chains.clear(); 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; }