static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dispbase) { if (!CU_DO_2DFILL(cu)) return; if (dispbase->first && ((DispList *) dispbase->first)->type == DL_SURF) { bevels_to_filledpoly(cu, dispbase); } else { const float z_up[3] = {0.0f, 0.0f, 1.0f}; BKE_displist_fill(dispbase, dispbase, z_up, false); } }
/* use specified dispbase */ int BKE_mesh_nurbs_displist_to_mdata(Object *ob, const ListBase *dispbase, MVert **r_allvert, int *r_totvert, MEdge **r_alledge, int *r_totedge, MLoop **r_allloop, MPoly **r_allpoly, MLoopUV **r_alluv, int *r_totloop, int *r_totpoly) { Curve *cu = ob->data; DispList *dl; MVert *mvert; MPoly *mpoly; MLoop *mloop; MLoopUV *mloopuv = NULL; MEdge *medge; const float *data; int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totpoly = 0; int p1, p2, p3, p4, *index; const bool conv_polys = ((CU_DO_2DFILL(cu) == false) || /* 2d polys are filled with DL_INDEX3 displists */ (ob->type == OB_SURF)); /* surf polys are never filled */ /* count */ dl = dispbase->first; while (dl) { if (dl->type == DL_SEGM) { totvert += dl->parts * dl->nr; totedge += dl->parts * (dl->nr - 1); } else if (dl->type == DL_POLY) { if (conv_polys) { totvert += dl->parts * dl->nr; totedge += dl->parts * dl->nr; } } else if (dl->type == DL_SURF) { int tot; totvert += dl->parts * dl->nr; tot = (dl->parts - 1 + ((dl->flag & DL_CYCL_V) == 2)) * (dl->nr - 1 + (dl->flag & DL_CYCL_U)); totpoly += tot; totloop += tot * 4; } else if (dl->type == DL_INDEX3) { int tot; totvert += dl->nr; tot = dl->parts; totpoly += tot; totloop += tot * 3; } dl = dl->next; } if (totvert == 0) { /* error("can't convert"); */ /* Make Sure you check ob->data is a curve */ return -1; } *r_allvert = mvert = MEM_calloc_arrayN(totvert, sizeof(MVert), "nurbs_init mvert"); *r_alledge = medge = MEM_calloc_arrayN(totedge, sizeof(MEdge), "nurbs_init medge"); *r_allloop = mloop = MEM_calloc_arrayN( totpoly, 4 * sizeof(MLoop), "nurbs_init mloop"); // totloop *r_allpoly = mpoly = MEM_calloc_arrayN(totpoly, sizeof(MPoly), "nurbs_init mloop"); if (r_alluv) { *r_alluv = mloopuv = MEM_calloc_arrayN(totpoly, 4 * sizeof(MLoopUV), "nurbs_init mloopuv"); } /* verts and faces */ vertcount = 0; dl = dispbase->first; while (dl) { const bool is_smooth = (dl->rt & CU_SMOOTH) != 0; if (dl->type == DL_SEGM) { startvert = vertcount; a = dl->parts * dl->nr; data = dl->verts; while (a--) { copy_v3_v3(mvert->co, data); data += 3; vertcount++; mvert++; } for (a = 0; a < dl->parts; a++) { ofs = a * dl->nr; for (b = 1; b < dl->nr; b++) { medge->v1 = startvert + ofs + b - 1; medge->v2 = startvert + ofs + b; medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW; medge++; } } } else if (dl->type == DL_POLY) { if (conv_polys) { startvert = vertcount; a = dl->parts * dl->nr; data = dl->verts; while (a--) { copy_v3_v3(mvert->co, data); data += 3; vertcount++; mvert++; } for (a = 0; a < dl->parts; a++) { ofs = a * dl->nr; for (b = 0; b < dl->nr; b++) { medge->v1 = startvert + ofs + b; if (b == dl->nr - 1) { medge->v2 = startvert + ofs; } else { medge->v2 = startvert + ofs + b + 1; } medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW; medge++; } } } } else if (dl->type == DL_INDEX3) { startvert = vertcount; a = dl->nr; data = dl->verts; while (a--) { copy_v3_v3(mvert->co, data); data += 3; vertcount++; mvert++; } a = dl->parts; index = dl->index; while (a--) { mloop[0].v = startvert + index[0]; mloop[1].v = startvert + index[2]; mloop[2].v = startvert + index[1]; mpoly->loopstart = (int)(mloop - (*r_allloop)); mpoly->totloop = 3; mpoly->mat_nr = dl->col; if (mloopuv) { int i; for (i = 0; i < 3; i++, mloopuv++) { mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1); mloopuv->uv[1] = 0.0f; } } if (is_smooth) { mpoly->flag |= ME_SMOOTH; } mpoly++; mloop += 3; index += 3; } } else if (dl->type == DL_SURF) { startvert = vertcount; a = dl->parts * dl->nr; data = dl->verts; while (a--) { copy_v3_v3(mvert->co, data); data += 3; vertcount++; mvert++; } for (a = 0; a < dl->parts; a++) { if ((dl->flag & DL_CYCL_V) == 0 && a == dl->parts - 1) { break; } if (dl->flag & DL_CYCL_U) { /* p2 -> p1 -> */ p1 = startvert + dl->nr * a; /* p4 -> p3 -> */ p2 = p1 + dl->nr - 1; /* -----> next row */ p3 = p1 + dl->nr; p4 = p2 + dl->nr; b = 0; } else { p2 = startvert + dl->nr * a; p1 = p2 + 1; p4 = p2 + dl->nr; p3 = p1 + dl->nr; b = 1; } if ((dl->flag & DL_CYCL_V) && a == dl->parts - 1) { p3 -= dl->parts * dl->nr; p4 -= dl->parts * dl->nr; } for (; b < dl->nr; b++) { mloop[0].v = p1; mloop[1].v = p3; mloop[2].v = p4; mloop[3].v = p2; mpoly->loopstart = (int)(mloop - (*r_allloop)); mpoly->totloop = 4; mpoly->mat_nr = dl->col; if (mloopuv) { int orco_sizeu = dl->nr - 1; int orco_sizev = dl->parts - 1; int i; /* exception as handled in convertblender.c too */ if (dl->flag & DL_CYCL_U) { orco_sizeu++; if (dl->flag & DL_CYCL_V) { orco_sizev++; } } else if (dl->flag & DL_CYCL_V) { orco_sizev++; } for (i = 0; i < 4; i++, mloopuv++) { /* find uv based on vertex index into grid array */ int v = mloop[i].v - startvert; mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev; mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu; /* cyclic correction */ if ((i == 1 || i == 2) && mloopuv->uv[0] == 0.0f) { mloopuv->uv[0] = 1.0f; } if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f) { mloopuv->uv[1] = 1.0f; } } } if (is_smooth) { mpoly->flag |= ME_SMOOTH; } mpoly++; mloop += 4; p4 = p3; p3++; p2 = p1; p1++; } } } dl = dl->next; } if (totpoly) { make_edges_mdata_extend(r_alledge, &totedge, *r_allpoly, *r_allloop, totpoly); } *r_totpoly = totpoly; *r_totloop = totloop; *r_totedge = totedge; *r_totvert = totvert; return 0; }