📄 findseam.cpp
字号:
top2 = top1; } array_loop(seam_pile, x) { this_one = (SEAM *) array_value (seam_pile, x); dist = seam->location - this_one->location; if (-SPLIT_CLOSENESS < dist && dist < SPLIT_CLOSENESS && seam->priority + this_one->priority < ok_split) { if ( /*!tessedit_fix_sideways_chops || */ (this_one->split1->point1->pos.y >= top1 && this_one->split1->point2->pos.y >= top1 || this_one->split1->point1->pos.y <= bottom1 && this_one->split1->point2->pos.y <= bottom1) && (this_one->split1->point1->pos.y >= top2 && this_one->split1->point2->pos.y >= top2 || this_one->split1->point1->pos.y <= bottom2 && this_one->split1->point2->pos.y <= bottom2) && (this_one->split2 == NULL || (this_one->split2->point1->pos.y >= top1 && this_one->split2->point2->pos.y >= top1 || this_one->split2->point1->pos.y <= bottom1 && this_one->split2->point2->pos.y <= bottom1) && (this_one->split2->point1->pos.y >= top2 && this_one->split2->point2->pos.y >= top2 || this_one->split2->point1->pos.y <= bottom2 && this_one->split2->point2->pos.y <= bottom2))) { new_one = join_two_seams (seam, this_one); if (chop_debug > 1) print_seam ("Combo priority ", new_one); add_seam_to_queue (seam_queue, new_one, new_one->priority); } } }}/********************************************************************** * constrained_split * * Constrain this split to obey certain rules. It must not cross any * inner outline. It must not cut off a small chunk of the outline. **********************************************************************/INT16 constrained_split(SPLIT *split, TBLOB *blob) { TESSLINE *outline; if (is_little_chunk (split->point1, split->point2)) return (FALSE); for (outline = blob->outlines; outline; outline = outline->next) { if (split_bounds_overlap (split, outline) && crosses_outline (split->point1, split->point2, outline->loop)) { return (FALSE); } } return (TRUE);}/********************************************************************** * delete_seam_pile * * Delete the seams that are held in the seam pile. Destroy the splits * that are referenced by these seams. **********************************************************************/void delete_seam_pile(SEAM_PILE seam_pile) { INT16 x; array_loop(seam_pile, x) { delete_seam ((SEAM *) array_value (seam_pile, x)); } array_free(seam_pile);}/********************************************************************** * pick_good_seam * * Find and return a good seam that will split this blob into two pieces. * Work from the outlines provided. **********************************************************************/SEAM *pick_good_seam(TBLOB *blob) { SEAM_QUEUE seam_queue; SEAM_PILE seam_pile; POINT_GROUP point_heap; PRIORITY priority; EDGEPT *edge; EDGEPT *points[MAX_NUM_POINTS]; SEAM *seam = NULL; TESSLINE *outline; INT16 num_points = 0;#ifndef GRAPHICS_DISABLED if (chop_debug) display_splits = TRUE; draw_blob_edges(blob);#endif point_heap = MakeHeap (MAX_NUM_POINTS); for (outline = blob->outlines; outline; outline = outline->next) prioritize_points(outline, point_heap); while (HeapPop (point_heap, &priority, &edge) == OK) { if (num_points < MAX_NUM_POINTS) points[num_points++] = (EDGEPT *) edge; } FreeHeap(point_heap); /* Initialize queue & pile */ create_seam_pile(seam_pile); create_seam_queue(seam_queue); try_point_pairs(points, num_points, seam_queue, &seam_pile, &seam, blob); try_vertical_splits(points, num_points, seam_queue, &seam_pile, &seam, blob); if (seam == NULL) { choose_best_seam(seam_queue, &seam_pile, NULL, BAD_PRIORITY, &seam, blob); } else if (seam->priority > good_split) { choose_best_seam (seam_queue, &seam_pile, NULL, seam->priority, &seam, blob); } delete_seam_queue(seam_queue); delete_seam_pile(seam_pile); if (seam) { if (seam->priority > ok_split) { delete_seam(seam); seam = NULL; }#ifndef GRAPHICS_DISABLED else if (display_splits) { if (seam->split1) mark_split (seam->split1); if (seam->split2) mark_split (seam->split2); if (seam->split3) mark_split (seam->split3); if (chop_debug > 1) { update_edge_window(); edge_window_wait(); } }#endif } if (chop_debug) display_splits = FALSE; return (seam);}/********************************************************************** * seam_priority * * Assign a full priority value to the seam. **********************************************************************/PRIORITY seam_priority(SEAM *seam, INT16 xmin, INT16 xmax) { PRIORITY priority; if (seam->split1 == NULL) priority = 0; else if (seam->split2 == NULL) { priority = (seam->priority + full_split_priority (seam->split1, xmin, xmax)); } else if (seam->split3 == NULL) { split_outline (seam->split2->point1, seam->split2->point2); priority = (seam->priority + full_split_priority (seam->split1, xmin, xmax)); unsplit_outlines (seam->split2->point1, seam->split2->point2); } else { split_outline (seam->split2->point1, seam->split2->point2); split_outline (seam->split3->point1, seam->split3->point2); priority = (seam->priority + full_split_priority (seam->split1, xmin, xmax)); unsplit_outlines (seam->split3->point1, seam->split3->point2); unsplit_outlines (seam->split2->point1, seam->split2->point2); } return (priority);}/********************************************************************** * try_point_pairs * * Try all the splits that are produced by pairing critical points * together. See if any of them are suitable for use. Use a seam * queue and seam pile that have already been initialized and used. **********************************************************************/voidtry_point_pairs (EDGEPT * points[MAX_NUM_POINTS],INT16 num_points,SEAM_QUEUE seam_queue,SEAM_PILE * seam_pile, SEAM ** seam, TBLOB * blob) { INT16 x; INT16 y; SPLIT *split; PRIORITY priority; for (x = 0; x < num_points; x++) { for (y = x + 1; y < num_points; y++) { if (points[y] && weighted_edgept_dist (points[x], points[y], x_y_weight) < split_length && points[x] != points[y]->next && points[y] != points[x]->next && !is_exterior_point (points[x], points[y]) && !is_exterior_point (points[y], points[x])) { split = new_split (points[x], points[y]); priority = partial_split_priority (split); choose_best_seam(seam_queue, seam_pile, split, priority, seam, blob); if (*seam && (*seam)->priority < good_split) return; } } }}/********************************************************************** * try_vertical_splits * * Try all the splits that are produced by vertical projection to see * if any of them are suitable for use. Use a seam queue and seam pile * that have already been initialized and used. **********************************************************************/voidtry_vertical_splits (EDGEPT * points[MAX_NUM_POINTS],INT16 num_points,SEAM_QUEUE seam_queue,SEAM_PILE * seam_pile, SEAM ** seam, TBLOB * blob) { EDGEPT *vertical_point = NULL; SPLIT *split; INT16 x; PRIORITY priority; TESSLINE *outline; for (x = 0; x < num_points; x++) { if (*seam != NULL && (*seam)->priority < good_split) return; vertical_point = NULL; for (outline = blob->outlines; outline; outline = outline->next) { vertical_projection_point (points[x], outline->loop, &vertical_point); } if (vertical_point && points[x] != vertical_point->next && vertical_point != points[x]->next && weighted_edgept_dist (points[x], vertical_point, x_y_weight) < split_length) { split = new_split (points[x], vertical_point); priority = partial_split_priority (split); choose_best_seam(seam_queue, seam_pile, split, priority, seam, blob); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -