本文整理汇总了C++中PathObject类的典型用法代码示例。如果您正苦于以下问题:C++ PathObject类的具体用法?C++ PathObject怎么用?C++ PathObject使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了PathObject类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: oscAction
void MuseScore::oscAction()
{
PathObject* pathObject = qobject_cast<PathObject*>(sender());
QString path = pathObject->path().mid(9);
QAction* a = getAction(path.toLocal8Bit().data());
a->trigger();
}
示例2: editor
void ToolsTest::editTool()
{
// Initialization
TestMap map;
TestMapEditor editor(map.map);
EditTool* tool = new EditPointTool(editor.editor, nullptr); // TODO: Refactor EditTool: MapEditorController and SymbolWidget pointers could be unnecessary
editor.editor->setTool(tool);
// Move the first coordinate of the line object
MapWidget* map_widget = editor.map_widget;
PathObject* object = map.line_object;
const MapCoord& coord = object->getCoordinate(0);
QPointF drag_start_pos = map_widget->mapToViewport(coord);
QPointF drag_end_pos = drag_start_pos + QPointF(0, -50);
// Clear selection.
map.map->clearObjectSelection(false);
QVERIFY(map.map->selectedObjects().empty());
// Click to select the object
editor.simulateClick(drag_start_pos);
QCOMPARE(map.map->getFirstSelectedObject(), object);
// Drag the coordinate to the new position
editor.simulateDrag(drag_start_pos, drag_end_pos);
// Check position deviation
QPointF difference = map_widget->mapToViewport(coord) - drag_end_pos;
QCOMPARE(qMax(qAbs(difference.x()), 0.1), 0.1);
QCOMPARE(qMax(qAbs(difference.y()), 0.1), 0.1);
// Cleanup
editor.editor->setTool(nullptr);
}
示例3: Q_ASSERT
bool CutTool::findEditPoint(PathCoord& out_edit_point, PathObject*& out_edit_object, MapCoordF cursor_pos_map, int with_type, int without_type, MapWidget* widget)
{
Map* map = this->map();
out_edit_object = nullptr;
if (hover_state == HoverFlag::OverObjectNode &&
hover_object->getSymbol()->getContainedTypes() & with_type &&
!(hover_object->getSymbol()->getContainedTypes() & without_type))
{
// Hovering over a point of a line
if (hover_object->getType() != Object::Path)
{
Q_ASSERT(!"TODO: make this work for non-path objects");
return false;
}
out_edit_object = reinterpret_cast<PathObject*>(hover_object);
out_edit_point = out_edit_object->findPathCoordForIndex(hover_point);
}
else
{
// Check if a line segment was clicked
float min_distance_sq = 999999;
for (const auto object : map->selectedObjects())
{
if (!(object->getSymbol()->getContainedTypes() & with_type) ||
object->getSymbol()->getContainedTypes() & without_type)
{
continue;
}
if (object->getType() != Object::Path)
{
Q_ASSERT(!"TODO: make this work for non-path objects");
continue;
}
PathObject* path = reinterpret_cast<PathObject*>(object);
float distance_sq;
PathCoord path_coord;
path->calcClosestPointOnPath(cursor_pos_map, distance_sq, path_coord);
float click_tolerance_map = 0.001f * widget->getMapView()->pixelToLength(clickTolerance());
if (distance_sq < min_distance_sq && distance_sq <= click_tolerance_map*click_tolerance_map)
{
min_distance_sq = distance_sq;
out_edit_object = path;
out_edit_point = path_coord;
}
}
}
return out_edit_object != nullptr;
}
示例4: guessDominantColor
void TextSymbol::createBaselineRenderables(
const TextObject* text_object,
const VirtualCoordVector& coords,
ObjectRenderables& output) const
{
const MapColor* dominant_color = guessDominantColor();
if (dominant_color && text_object->getNumLines() > 0)
{
// Insert text boundary
LineSymbol line_symbol;
line_symbol.setColor(dominant_color);
line_symbol.setLineWidth(0);
const TextObjectLineInfo* line = text_object->getLineInfo(0);
QRectF text_bbox(line->line_x, line->line_y - line->ascent, line->width, line->ascent + line->descent);
for (int i = 1; i < text_object->getNumLines(); ++i)
{
const TextObjectLineInfo* line = text_object->getLineInfo(i);
rectInclude(text_bbox, QRectF(line->line_x, line->line_y - line->ascent, line->width, line->ascent + line->descent));
}
Q_UNUSED(coords); // coords should be used for calcTextToMapTransform()
QTransform text_to_map = text_object->calcTextToMapTransform();
PathObject path;
path.addCoordinate(MapCoord(text_to_map.map(text_bbox.topLeft())));
path.addCoordinate(MapCoord(text_to_map.map(text_bbox.topRight())));
path.addCoordinate(MapCoord(text_to_map.map(text_bbox.bottomRight())));
path.addCoordinate(MapCoord(text_to_map.map(text_bbox.bottomLeft())));
path.parts().front().setClosed(true, true);
path.updatePathCoords();
LineRenderable* line_renderable = new LineRenderable(&line_symbol, path.parts().front(), false);
output.insertRenderable(line_renderable);
}
}
示例5: sender
void MuseScore::oscMuteChannel(double val)
{
if(!cs)
return;
PathObject* po = (PathObject*) sender();
int i = po->path().mid(5).toInt() - 1;
QList<MidiMapping>* mms = cs->midiMapping();
if( i >= 0 && i < mms->size()) {
MidiMapping mm = mms->at(i);
Channel* channel = mm.articulation;
channel->mute = (val==0.0f ? false : true);
if (mixer)
mixer->partEdit(i)->mute->setCheckState(val==0.0f ? Qt::Unchecked:Qt::Checked);
}
}
示例6: sender
void MuseScore::oscVolChannel(double val)
{
if(!cs)
return;
PathObject* po = (PathObject*) sender();
int i = po->path().mid(4).toInt() - 1;
QList<MidiMapping>* mms = cs->midiMapping();
if( i >= 0 && i < mms->size()) {
MidiMapping mm = mms->at(i);
Channel* channel = mm.articulation;
int iv = lrint(val*127);
seq->setController(channel->channel, CTRL_VOLUME, iv);
channel->volume = iv;
if (iledit)
iledit->partEdit(i)->volume->setValue(iv);
}
}
示例7: getPartIndex
UndoStep* SwitchDashesUndoStep::undo()
{
int const part_index = getPartIndex();
SwitchDashesUndoStep* undo_step = new SwitchDashesUndoStep(map);
undo_step->setPartIndex(part_index);
MapPart* part = map->getPart(part_index);
for (ObjectList::iterator it = modified_objects.begin(), end = modified_objects.end(); it != end; ++it)
{
PathObject* object = reinterpret_cast<PathObject*>(part->getObject(*it));
object->reverse();
object->update();
undo_step->addObject(*it);
}
return undo_step;
}
示例8: map
bool DrawPathTool::removeLastPointFromSelectedPath()
{
if (editingInProgress() || map()->getNumSelectedObjects() != 1)
{
return false;
}
Object* object = map()->getFirstSelectedObject();
if (object->getType() != Object::Path)
{
return false;
}
PathObject* path = object->asPath();
if (path->parts().size() != 1)
{
return false;
}
int points_on_path = 0;
int num_coords = path->getCoordinateCount();
for (int i = 0; i < num_coords && points_on_path < 3; ++i)
{
++points_on_path;
if (path->getCoordinate(i).isCurveStart())
{
i += 2; // Skip the control points.
}
}
if (points_on_path < 3)
{
// Too few points after deleting the last: delete the whole object.
map()->deleteSelectedObjects();
return true;
}
ReplaceObjectsUndoStep* undo_step = new ReplaceObjectsUndoStep(map());
Object* undo_duplicate = object->duplicate();
undo_duplicate->setMap(map());
undo_step->addObject(object, undo_duplicate);
map()->push(undo_step);
updateDirtyRect();
path->parts().front().setClosed(false);
path->deleteCoordinate(num_coords - 1, false);
path->update();
map()->setObjectsDirty();
map()->emitSelectionEdited();
return true;
}
示例9: Q_UNUSED
void BooleanTool::rebuildTwoIndexSegment(
ClipperLib::Path::size_type start_index,
ClipperLib::Path::size_type end_index,
bool sequence_increasing,
const ClipperLib::Path& polygon,
const PolyMap& polymap,
PathObject* object)
{
Q_UNUSED(sequence_increasing); // only used in Q_ASSERT.
PathCoordInfo start_info = polymap.value(polygon.at(start_index));
PathCoordInfo end_info = polymap.value(polygon.at(end_index));
PathObject* original = end_info.first->path;
bool coords_increasing;
bool is_curve;
int coord_index;
if (start_info.second->index == end_info.second->index)
{
coord_index = end_info.second->index;
bool found = checkSegmentMatch(original, coord_index, polygon, start_index, end_index, coords_increasing, is_curve);
if (!found)
{
object->getCoordinate(object->getCoordinateCount() - 1).setCurveStart(false);
rebuildCoordinate(end_index, polygon, polymap, object);
return;
}
Q_ASSERT(coords_increasing == sequence_increasing);
}
else
{
coord_index = end_info.second->index;
bool found = checkSegmentMatch(original, coord_index, polygon, start_index, end_index, coords_increasing, is_curve);
if (!found)
{
coord_index = start_info.second->index;
found = checkSegmentMatch(original, coord_index, polygon, start_index, end_index, coords_increasing, is_curve);
if (!found)
{
object->getCoordinate(object->getCoordinateCount() - 1).setCurveStart(false);
rebuildCoordinate(end_index, polygon, polymap, object);
return;
}
}
}
if (!is_curve)
object->getCoordinate(object->getCoordinateCount() - 1).setCurveStart(false);
if (coords_increasing)
{
object->addCoordinate(resetCoordinate(original->getCoordinate(coord_index + 1)));
if (is_curve)
{
object->addCoordinate(original->getCoordinate(coord_index + 2));
object->addCoordinate(resetCoordinate(original->getCoordinate(coord_index + 3)));
}
}
else
{
if (is_curve)
{
object->addCoordinate(resetCoordinate(original->getCoordinate(coord_index + 2)));
object->addCoordinate(original->getCoordinate(coord_index + 1));
}
object->addCoordinate(resetCoordinate(original->getCoordinate(coord_index + 0)));
}
}
示例10: tr
void CutTool::pathFinished(PathObject* split_path)
{
Map* map = this->map();
// Get path endpoint and check if it is on the area boundary
const MapCoordVector& path_coords = split_path->getRawCoordinateVector();
MapCoord path_end = path_coords.at(path_coords.size() - 1);
PathObject* edited_path = reinterpret_cast<PathObject*>(edit_object);
PathCoord end_path_coord;
float distance_sq;
edited_path->calcClosestPointOnPath(MapCoordF(path_end), distance_sq, end_path_coord);
float click_tolerance_map = 0.001 * edit_widget->getMapView()->pixelToLength(clickTolerance());
if (distance_sq > click_tolerance_map*click_tolerance_map)
{
QMessageBox::warning(window(), tr("Error"), tr("The split line must end on the area boundary!"));
pathAborted();
return;
}
else if (drag_part_index != edited_path->findPartIndexForIndex(end_path_coord.index))
{
QMessageBox::warning(window(), tr("Error"), tr("Start and end of the split line are at different parts of the object!"));
pathAborted();
return;
}
else if (drag_start_len == end_path_coord.clen)
{
QMessageBox::warning(window(), tr("Error"), tr("Start and end of the split line are at the same position!"));
pathAborted();
return;
}
Q_ASSERT(split_path->parts().size() == 1);
split_path->parts().front().setClosed(false);
split_path->setCoordinate(split_path->getCoordinateCount() - 1, MapCoord(end_path_coord.pos));
// Do the splitting
const double split_threshold = 0.01;
MapPart* part = map->getCurrentPart();
AddObjectsUndoStep* add_step = new AddObjectsUndoStep(map);
add_step->addObject(part->findObjectIndex(edited_path), edited_path);
map->removeObjectFromSelection(edited_path, false);
map->deleteObject(edited_path, true);
map->setObjectsDirty();
DeleteObjectsUndoStep* delete_step = new DeleteObjectsUndoStep(map);
PathObject* holes = nullptr; // if the edited path contains holes, they are saved in this temporary object
if (edited_path->parts().size() > 1)
{
holes = edited_path->duplicate()->asPath();
holes->deletePart(0);
}
bool ok; Q_UNUSED(ok); // "ok" is only used in Q_ASSERT.
PathObject* parts[2] = { new PathObject { edited_path->parts().front() }, nullptr };
const PathPart& drag_part = edited_path->parts()[drag_part_index];
if (drag_part.isClosed())
{
parts[1] = new PathObject { *parts[0] };
parts[0]->changePathBounds(drag_part_index, drag_start_len, end_path_coord.clen);
ok = parts[0]->connectIfClose(split_path, split_threshold);
Q_ASSERT(ok);
parts[1]->changePathBounds(drag_part_index, end_path_coord.clen, drag_start_len);
ok = parts[1]->connectIfClose(split_path, split_threshold);
Q_ASSERT(ok);
}
else
{
float min_cut_pos = qMin(drag_start_len, end_path_coord.clen);
float max_cut_pos = qMax(drag_start_len, end_path_coord.clen);
float path_len = drag_part.path_coords.back().clen;
if (min_cut_pos <= 0 && max_cut_pos >= path_len)
{
ok = parts[0]->connectIfClose(split_path, split_threshold);
Q_ASSERT(ok);
parts[1] = new PathObject { *split_path };
parts[1]->setSymbol(edited_path->getSymbol(), false);
}
else if (min_cut_pos <= 0 || max_cut_pos >= path_len)
{
float cut_pos = (min_cut_pos <= 0) ? max_cut_pos : min_cut_pos;
parts[1] = new PathObject { *parts[0] };
parts[0]->changePathBounds(drag_part_index, 0, cut_pos);
ok = parts[0]->connectIfClose(split_path, split_threshold);
Q_ASSERT(ok);
parts[1]->changePathBounds(drag_part_index, cut_pos, path_len);
ok = parts[1]->connectIfClose(split_path, split_threshold);
Q_ASSERT(ok);
}
else
{
parts[1] = new PathObject { *parts[0] };
//.........这里部分代码省略.........
示例11: MapCoordF
void EditPointTool::updateHoverState(MapCoordF cursor_pos)
{
HoverState new_hover_state = OverNothing;
const Object* new_hover_object = nullptr;
MapCoordVector::size_type new_hover_point = no_point;
if (text_editor)
{
handle_offset = MapCoordF(0, 0);
}
else if (!map()->selectedObjects().empty())
{
if (map()->selectedObjects().size() <= max_objects_for_handle_display)
{
// Try to find object node.
auto best_distance_sq = std::numeric_limits<double>::max();
for (const auto object : map()->selectedObjects())
{
MapCoordF handle_pos;
auto hover_point = findHoverPoint(cur_map_widget->mapToViewport(cursor_pos), cur_map_widget, object, true, &handle_pos);
if (hover_point == no_point)
continue;
auto distance_sq = cursor_pos.distanceSquaredTo(handle_pos);
if (distance_sq < best_distance_sq)
{
new_hover_state |= OverObjectNode;
new_hover_object = object;
new_hover_point = hover_point;
best_distance_sq = distance_sq;
handle_offset = handle_pos - cursor_pos;
}
}
if (!new_hover_state.testFlag(OverObjectNode))
{
// No object node found. Try to find path object edge.
/// \todo De-duplicate: Copied from EditLineTool
auto click_tolerance_sq = qPow(0.001 * cur_map_widget->getMapView()->pixelToLength(clickTolerance()), 2);
for (auto object : map()->selectedObjects())
{
if (object->getType() == Object::Path)
{
PathObject* path = object->asPath();
float distance_sq;
PathCoord path_coord;
path->calcClosestPointOnPath(cursor_pos, distance_sq, path_coord);
if (distance_sq >= +0.0 &&
distance_sq < best_distance_sq &&
distance_sq < qMax(click_tolerance_sq, qPow(path->getSymbol()->calculateLargestLineExtent(map()), 2)))
{
new_hover_state |= OverPathEdge;
new_hover_object = path;
new_hover_point = path_coord.index;
best_distance_sq = distance_sq;
handle_offset = path_coord.pos - cursor_pos;
}
}
}
}
}
if (!new_hover_state.testFlag(OverObjectNode) && selection_extent.isValid())
{
QRectF selection_extent_viewport = cur_map_widget->mapToViewport(selection_extent);
if (pointOverRectangle(cur_map_widget->mapToViewport(cursor_pos), selection_extent_viewport))
{
new_hover_state |= OverFrame;
handle_offset = closestPointOnRect(cursor_pos, selection_extent) - cursor_pos;
}
}
}
if (new_hover_state != hover_state ||
new_hover_object != hover_object ||
new_hover_point != hover_point)
{
hover_state = new_hover_state;
// We have got a Map*, so we may get an non-const Object*.
hover_object = const_cast<Object*>(new_hover_object);
hover_point = new_hover_point;
if (hover_state != OverNothing)
start_drag_distance = 0;
else
start_drag_distance = Settings::getInstance().getStartDragDistancePx();
updateDirtyRect();
}
Q_ASSERT((hover_state.testFlag(OverObjectNode) || hover_state.testFlag(OverPathEdge)) == (hover_object != nullptr));
}
示例12: Q_ASSERT
void EditPointTool::clickPress()
{
Q_ASSERT(!hover_state.testFlag(OverObjectNode) ||
!hover_state.testFlag(OverPathEdge) ||
hover_object);
if (hover_state.testFlag(OverPathEdge) &&
active_modifiers & Qt::ControlModifier)
{
// Add new point to path
PathObject* path = hover_object->asPath();
float distance_sq;
PathCoord path_coord;
path->calcClosestPointOnPath(cur_pos_map, distance_sq, path_coord);
float click_tolerance_map_sq = cur_map_widget->getMapView()->pixelToLength(clickTolerance());
click_tolerance_map_sq = click_tolerance_map_sq * click_tolerance_map_sq;
if (distance_sq <= click_tolerance_map_sq)
{
startEditing();
QScopedValueRollback<bool> no_effect_rollback(no_more_effect_on_click);
no_more_effect_on_click = true;
startDragging();
hover_state = OverObjectNode;
hover_point = path->subdivide(path_coord);
if (addDashPointDefault() ^ space_pressed)
{
MapCoord point = path->getCoordinate(hover_point);
point.setDashPoint(true);
path->setCoordinate(hover_point, point);
map()->emitSelectionEdited();
}
startEditingSetup();
updatePreviewObjects();
}
}
else if (hover_state.testFlag(OverObjectNode) &&
hover_object->getType() == Object::Path)
{
PathObject* hover_object = this->hover_object->asPath();
Q_ASSERT(hover_point < hover_object->getCoordinateCount());
if (space_pressed &&
!hover_object->isCurveHandle(hover_point))
{
// Switch point between dash / normal point
createReplaceUndoStep(hover_object);
MapCoord& hover_coord = hover_object->getCoordinate(hover_point);
hover_coord.setDashPoint(!hover_coord.isDashPoint());
hover_object->update();
updateDirtyRect();
no_more_effect_on_click = true;
}
else if (active_modifiers & Qt::ControlModifier)
{
auto hover_point_part_index = hover_object->findPartIndexForIndex(hover_point);
PathPart& hover_point_part = hover_object->parts()[hover_point_part_index];
if (hover_object->isCurveHandle(hover_point))
{
// Convert the curve into a straight line
createReplaceUndoStep(hover_object);
hover_object->deleteCoordinate(hover_point, false);
hover_object->update();
map()->emitSelectionEdited();
updateHoverState(cur_pos_map);
updateDirtyRect();
no_more_effect_on_click = true;
}
else
{
// Delete the point
if (hover_point_part.countRegularNodes() <= 2 ||
( !(hover_object->getSymbol()->getContainedTypes() & Symbol::Line) &&
hover_point_part.size() <= 3 ) )
{
// Not enough remaining points -> delete the part and maybe object
if (hover_object->parts().size() == 1)
{
map()->removeObjectFromSelection(hover_object, false);
auto undo_step = new AddObjectsUndoStep(map());
auto part = map()->getCurrentPart();
int index = part->findObjectIndex(hover_object);
Q_ASSERT(index >= 0);
undo_step->addObject(index, hover_object);
map()->deleteObject(hover_object, true);
map()->push(undo_step);
map()->setObjectsDirty();
map()->emitSelectionEdited();
updateHoverState(cur_pos_map);
}
else
{
createReplaceUndoStep(hover_object);
hover_object->deletePart(hover_point_part_index);
hover_object->update();
map()->emitSelectionEdited();
//.........这里部分代码省略.........
示例13: PathObject
PathObject* TemplateTrack::importPathStart()
{
PathObject* path = new PathObject();
path->setSymbol(map->getUndefinedLine(), true);
return path;
}
示例14: tr
bool TemplateTrack::import(QWidget* dialog_parent)
{
if (track.getNumWaypoints() == 0 && track.getNumSegments() == 0)
{
QMessageBox::critical(dialog_parent, tr("Error"), tr("The path is empty, there is nothing to import!"));
return false;
}
const Track::ElementTags& tags = track.tags();
DeleteObjectsUndoStep* undo_step = new DeleteObjectsUndoStep(map);
MapPart* part = map->getCurrentPart();
std::vector< Object* > result;
map->clearObjectSelection(false);
if (track.getNumWaypoints() > 0)
{
int res = QMessageBox::question(dialog_parent, tr("Question"), tr("Should the waypoints be imported as a line going through all points?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
if (res == QMessageBox::No)
{
for (int i = 0; i < track.getNumWaypoints(); i++)
result.push_back(importWaypoint(templateToMap(track.getWaypoint(i).map_coord), track.getWaypointName(i)));
}
else
{
PathObject* path = importPathStart();
for (int i = 0; i < track.getNumWaypoints(); i++)
path->addCoordinate(MapCoord(templateToMap(track.getWaypoint(i).map_coord)));
importPathEnd(path);
path->setTag(QStringLiteral("name"), QString{});
result.push_back(path);
}
}
int skipped_paths = 0;
for (int i = 0; i < track.getNumSegments(); i++)
{
const int segment_size = track.getSegmentPointCount(i);
if (segment_size == 0)
{
++skipped_paths;
continue; // Don't create path without objects.
}
PathObject* path = importPathStart();
QString name = track.getSegmentName(i);
if (!tags[name].isEmpty())
{
path->setTags(tags[name]);
}
else
{
path->setTag(QStringLiteral("name"), name);
}
for (int j = 0; j < segment_size; j++)
{
const TrackPoint& track_point = track.getSegmentPoint(i, j);
auto coord = MapCoord { templateToMap(track_point.map_coord) };
if (track_point.is_curve_start && j < segment_size - 3)
coord.setCurveStart(true);
path->addCoordinate(coord);
}
if (track.getSegmentPoint(i, 0).gps_coord == track.getSegmentPoint(i, segment_size-1).gps_coord)
{
path->closeAllParts();
}
importPathEnd(path);
result.push_back(path);
}
for (int i = 0; i < (int)result.size(); ++i) // keep as separate loop to get the correct (final) indices
undo_step->addObject(part->findObjectIndex(result[i]));
map->setObjectsDirty();
map->push(undo_step);
map->emitSelectionChanged();
map->emitSelectionEdited(); // TODO: is this necessary here?
if (skipped_paths)
{
QMessageBox::information(
dialog_parent,
tr("Import problems"),
tr("%n path object(s) could not be imported (reason: missing coordinates).", "", skipped_paths) );
}
return true;
}
示例15: Q_ASSERT_X
void BooleanTool::executeForLine(const PathObject* area, const PathObject* line, BooleanTool::PathObjects& out_objects)
{
if (op != BooleanTool::Intersection && op != BooleanTool::Difference)
{
Q_ASSERT_X(false, "BooleanTool::executeForLine", "Only intersection and difference are supported.");
return; // no-op in release build
}
if (line->parts().size() != 1)
{
Q_ASSERT_X(false, "BooleanTool::executeForLine", "Only single-part lines are supported.");
return; // no-op in release build
}
// Calculate all intersection points of line with the area path
PathObject::Intersections intersections;
line->calcAllIntersectionsWith(area, intersections);
intersections.normalize();
PathObject* first_segment = NULL;
PathObject* last_segment = NULL;
const auto& part = line->parts().front();
const auto& path_coords = part.path_coords;
// Only one segment?
if (intersections.empty())
{
auto middle_length = part.length();
auto middle = SplitPathCoord::at(path_coords, middle_length);
if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
out_objects.push_back(new PathObject(*line));
return;
}
// First segment
auto middle_length = intersections[0].length / 2;
auto middle = SplitPathCoord::at(path_coords, middle_length);
if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
{
PathObject* segment = new PathObject(*line);
segment->changePathBounds(0, 0.0, intersections[0].length);
first_segment = segment;
}
// Middle segments
for (std::size_t i = 0; i < intersections.size() - 1; ++i)
{
middle_length = (intersections[i].length + intersections[i+1].length) / 2;
auto middle = SplitPathCoord::at(path_coords, middle_length);
if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
{
PathObject* segment = new PathObject(*line);
segment->changePathBounds(0, intersections[i].length, intersections[i+1].length);
out_objects.push_back(segment);
}
}
// Last segment
middle_length = (part.length() + intersections.back().length) / 2;
middle = SplitPathCoord::at(path_coords, middle_length);
if (area->isPointInsideArea(middle.pos) == (op == BooleanTool::Intersection))
{
PathObject* segment = new PathObject(*line);
segment->changePathBounds(0, intersections.back().length, part.length());
last_segment = segment;
}
// If the line was closed at the beginning, merge the first and last segments if they were kept both.
if (part.isClosed() && first_segment && last_segment)
{
last_segment->connectPathParts(0, first_segment, 0, false);
delete first_segment;
out_objects.push_back(last_segment);
}
else
{
if (first_segment)
out_objects.push_back(first_segment);
if (last_segment)
out_objects.push_back(last_segment);
}
}