static void testvertexnearedge(ScanFillContext *sf_ctx) { /* only vertices with (->h == 1) are being tested for * being close to an edge, if true insert */ ScanFillVert *eve; ScanFillEdge *eed, *ed1; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { if (eve->edge_tot == 1) { /* find the edge which has vertex eve, * note: we _know_ this will crash if 'ed1' becomes NULL * but this will never happen. */ for (ed1 = sf_ctx->filledgebase.first; !(ed1->v1 == eve || ed1->v2 == eve); ed1 = ed1->next) { /* do nothing */ } if (ed1->v1 == eve) { ed1->v1 = ed1->v2; ed1->v2 = eve; } for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) { if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) { if (compare_v2v2(eve->xy, eed->v1->xy, SF_EPSILON)) { ed1->v2 = eed->v1; eed->v1->edge_tot++; eve->edge_tot = 0; break; } else if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) { ed1->v2 = eed->v2; eed->v2->edge_tot++; eve->edge_tot = 0; break; } else { if (boundinsideEV(eed, eve)) { const float dist = dist_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy); if (dist < SF_EPSILON) { /* new edge */ ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve); /* printf("fill: vertex near edge %x\n", eve); */ ed1->f = 0; ed1->poly_nr = eed->poly_nr; eed->v1 = eve; eve->edge_tot = 3; break; } } } } } } } }
static void testvertexnearedge(ScanFillContext *sf_ctx) { /* only vertices with ->h==1 are being tested for * being close to an edge, if true insert */ ScanFillVert *eve; ScanFillEdge *eed, *ed1; for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) { if (eve->h == 1) { /* find the edge which has vertex eve */ ed1 = sf_ctx->filledgebase.first; while (ed1) { if (ed1->v1 == eve || ed1->v2 == eve) break; ed1 = ed1->next; } if (ed1->v1 == eve) { ed1->v1 = ed1->v2; ed1->v2 = eve; } for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) { if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) { if (compare_v3v3(eve->co, eed->v1->co, SF_EPSILON)) { ed1->v2 = eed->v1; eed->v1->h++; eve->h = 0; break; } else if (compare_v3v3(eve->co, eed->v2->co, SF_EPSILON)) { ed1->v2 = eed->v2; eed->v2->h++; eve->h = 0; break; } else { if (boundinsideEV(eed, eve)) { const float dist = dist_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy); if (dist < SF_EPSILON) { /* new edge */ ed1 = BLI_addfilledge(sf_ctx, eed->v1, eve); /* printf("fill: vertex near edge %x\n",eve); */ ed1->f = 0; ed1->poly_nr = eed->poly_nr; eed->v1 = eve; eve->h = 3; break; } } } } } } } }
static void testvertexnearedge(void) { /* only vertices with ->h==1 are being tested for being close to an edge, if true insert */ EditVert *eve; EditEdge *eed,*ed1; float dist,vec1[2],vec2[2],vec3[2]; eve= fillvertbase.first; while(eve) { if(eve->h==1) { vec3[0]= eve->co[cox]; vec3[1]= eve->co[coy]; /* find the edge which has vertex eve */ ed1= filledgebase.first; while(ed1) { if(ed1->v1==eve || ed1->v2==eve) break; ed1= ed1->next; } if(ed1->v1==eve) { ed1->v1= ed1->v2; ed1->v2= eve; } eed= filledgebase.first; while(eed) { if(eve!=eed->v1 && eve!=eed->v2 && eve->xs==eed->f1) { if(compare_v3v3(eve->co,eed->v1->co, COMPLIMIT)) { ed1->v2= eed->v1; eed->v1->h++; eve->h= 0; break; } else if(compare_v3v3(eve->co,eed->v2->co, COMPLIMIT)) { ed1->v2= eed->v2; eed->v2->h++; eve->h= 0; break; } else { vec1[0]= eed->v1->co[cox]; vec1[1]= eed->v1->co[coy]; vec2[0]= eed->v2->co[cox]; vec2[1]= eed->v2->co[coy]; if(boundinsideEV(eed,eve)) { dist= dist_to_line_v2(vec1,vec2,vec3); if(dist<COMPLIMIT) { /* new edge */ ed1= BLI_addfilledge(eed->v1, eve); /* printf("fill: vertex near edge %x\n",eve); */ ed1->f= ed1->h= 0; ed1->f1= eed->f1; eed->v1= eve; eve->h= 3; break; } } } } eed= eed->next; } } eve= eve->next; } }
static void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) { /* Blender */ struct Nurb *nu; struct VChar *che; struct BezTriple *bezt; /* Freetype2 */ FT_GlyphSlot glyph; FT_UInt glyph_index; FT_Outline ftoutline; float scale, height; float dx, dy; int j, k, l, m = 0; /* adjust font size */ height = ((double) face->bbox.yMax - (double) face->bbox.yMin); if (height != 0.0f) scale = 1.0f / height; else scale = 1.0f / 1000.0f; /* * Generate the character 3D data * * Get the FT Glyph index and load the Glyph */ glyph_index = FT_Get_Char_Index(face, charcode); err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP); /* If loading succeeded, convert the FT glyph to the internal format */ if (!err) { int *npoints; int *onpoints; /* First we create entry for the new character to the character list */ che = (VChar *) MEM_callocN(sizeof(struct VChar), "objfnt_char"); BLI_addtail(&vfd->characters, che); /* Take some data for modifying purposes */ glyph = face->glyph; ftoutline = glyph->outline; /* Set the width and character code */ che->index = charcode; che->width = glyph->advance.x * scale; /* Start converting the FT data */ npoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "endpoints"); onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints"); /* calculate total points of each contour */ for (j = 0; j < ftoutline.n_contours; j++) { if (j == 0) npoints[j] = ftoutline.contours[j] + 1; else npoints[j] = ftoutline.contours[j] - ftoutline.contours[j - 1]; } /* get number of on-curve points for beziertriples (including conic virtual on-points) */ for (j = 0; j < ftoutline.n_contours; j++) { for (k = 0; k < npoints[j]; k++) { l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k; if (ftoutline.tags[l] == FT_Curve_Tag_On) onpoints[j]++; if (k < npoints[j] - 1) { if (ftoutline.tags[l] == FT_Curve_Tag_Conic && ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) { onpoints[j]++; } } } } /* contour loop, bezier & conic styles merged */ for (j = 0; j < ftoutline.n_contours; j++) { /* add new curve */ nu = (Nurb *)MEM_callocN(sizeof(struct Nurb), "objfnt_nurb"); bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt"); BLI_addtail(&che->nurbsbase, nu); nu->type = CU_BEZIER; nu->pntsu = onpoints[j]; nu->resolu = 8; nu->flag = CU_2D; nu->flagu = CU_NURB_CYCLIC; nu->bezt = bezt; /* individual curve loop, start-end */ for (k = 0; k < npoints[j]; k++) { if (j > 0) l = k + ftoutline.contours[j - 1] + 1; else l = k; if (k == 0) m = l; /* virtual conic on-curve points */ if (k < npoints[j] - 1) { if (ftoutline.tags[l] == FT_Curve_Tag_Conic && ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) { dx = (ftoutline.points[l].x + ftoutline.points[l + 1].x) * scale / 2.0f; dy = (ftoutline.points[l].y + ftoutline.points[l + 1].y) * scale / 2.0f; /* left handle */ bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f; bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f; /* midpoint (virtual on-curve point) */ bezt->vec[1][0] = dx; bezt->vec[1][1] = dy; /* right handle */ bezt->vec[2][0] = (dx + (2 * ftoutline.points[l + 1].x) * scale) / 3.0f; bezt->vec[2][1] = (dy + (2 * ftoutline.points[l + 1].y) * scale) / 3.0f; bezt->h1 = bezt->h2 = HD_ALIGN; bezt->radius = 1.0f; bezt++; } } /* on-curve points */ if (ftoutline.tags[l] == FT_Curve_Tag_On) { /* left handle */ if (k > 0) { if (ftoutline.tags[l - 1] == FT_Curve_Tag_Cubic) { bezt->vec[0][0] = ftoutline.points[l - 1].x * scale; bezt->vec[0][1] = ftoutline.points[l - 1].y * scale; bezt->h1 = HD_FREE; } else if (ftoutline.tags[l - 1] == FT_Curve_Tag_Conic) { bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l - 1].x)) * scale / 3.0f; bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l - 1].y)) * scale / 3.0f; bezt->h1 = HD_FREE; } else { bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l - 1].x) * scale / 3.0f; bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l - 1].y) * scale / 3.0f; bezt->h1 = HD_VECT; } } else { /* first point on curve */ if (ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Cubic) { bezt->vec[0][0] = ftoutline.points[ftoutline.contours[j]].x * scale; bezt->vec[0][1] = ftoutline.points[ftoutline.contours[j]].y * scale; bezt->h1 = HD_FREE; } else if (ftoutline.tags[ftoutline.contours[j]] == FT_Curve_Tag_Conic) { bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[ftoutline.contours[j]].x)) * scale / 3.0f; bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[ftoutline.contours[j]].y)) * scale / 3.0f; bezt->h1 = HD_FREE; } else { bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[ftoutline.contours[j]].x) * scale / 3.0f; bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[ftoutline.contours[j]].y) * scale / 3.0f; bezt->h1 = HD_VECT; } } /* midpoint (on-curve point) */ bezt->vec[1][0] = ftoutline.points[l].x * scale; bezt->vec[1][1] = ftoutline.points[l].y * scale; /* right handle */ if (k < (npoints[j] - 1)) { if (ftoutline.tags[l + 1] == FT_Curve_Tag_Cubic) { bezt->vec[2][0] = ftoutline.points[l + 1].x * scale; bezt->vec[2][1] = ftoutline.points[l + 1].y * scale; bezt->h2 = HD_FREE; } else if (ftoutline.tags[l + 1] == FT_Curve_Tag_Conic) { bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l + 1].x)) * scale / 3.0f; bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l + 1].y)) * scale / 3.0f; bezt->h2 = HD_FREE; } else { bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l + 1].x) * scale / 3.0f; bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l + 1].y) * scale / 3.0f; bezt->h2 = HD_VECT; } } else { /* last point on curve */ if (ftoutline.tags[m] == FT_Curve_Tag_Cubic) { bezt->vec[2][0] = ftoutline.points[m].x * scale; bezt->vec[2][1] = ftoutline.points[m].y * scale; bezt->h2 = HD_FREE; } else if (ftoutline.tags[m] == FT_Curve_Tag_Conic) { bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[m].x)) * scale / 3.0f; bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[m].y)) * scale / 3.0f; bezt->h2 = HD_FREE; } else { bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[m].x) * scale / 3.0f; bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[m].y) * scale / 3.0f; bezt->h2 = HD_VECT; } } /* get the handles that are aligned, tricky... * dist_to_line_v2, check if the three beztriple points are on one line * len_squared_v2v2, see if there's a distance between the three points * len_squared_v2v2 again, to check the angle between the handles * finally, check if one of them is a vector handle */ if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) && (dist_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) < 0.001f) && (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > 0.0001f * 0.0001f) && (len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > 0.0001f * 0.0001f) && (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > 0.0002f * 0.0001f) && (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]), len_squared_v2v2(bezt->vec[1], bezt->vec[2])))) { bezt->h1 = bezt->h2 = HD_ALIGN; } bezt->radius = 1.0f; bezt++; } } } if (npoints) MEM_freeN(npoints); if (onpoints) MEM_freeN(onpoints); } }