void Transformable::set_transform(uint64 idx) { _F_ int son[25]; int i = 0; while (idx > 0) { son[i++] = (idx - 1) & SUB_ELEMENT_MASK; idx = (idx - 1) >> SUB_ELEMENT_BITS; } reset_transform(); for (int k = i - 1; k >= 0; k--) push_transform(son[k]); }
void Transformable::set_transform(uint64_t idx) { int son[25]; int i = 0; while (idx > 0) { son[i++] = (idx - 1) & 7; idx = (idx - 1) >> 3; } reset_transform(); for (int k = i-1; k >= 0; k--) push_transform(son[k]); }
void TransformSetter::allocate( Canvas* c, const Allocation& a, Extension& ext ) { /* * Shouldn't need to test for nil canvas, but some old * applications (notably doc) pass nil as a canvas * when doing certain kinds of allocation. */ if (c != nil) { push_transform(c, a, natural_allocation_); MonoGlyph::allocate(c, natural_allocation_, ext); c->pop_transform(); } }
void TransformSetter::print(Printer* p, const Allocation& a) const { push_transform(p, a, natural_allocation_); MonoGlyph::print(p, natural_allocation_); p->pop_transform(); }
void TransformSetter::draw(Canvas* c, const Allocation& a) const { push_transform(c, a, natural_allocation_); MonoGlyph::draw(c, natural_allocation_); c->pop_transform(); }
void Vectorizer::process_triangle(int iv0, int iv1, int iv2, int level, scalar* xval, scalar* yval, double* phx, double* phy, int* idx) { if (level < LIN_MAX_LEVEL) { int i; if (!(level & 1)) { // obtain solution values and physical element coordinates xsln->set_quad_order(1, xitem); ysln->set_quad_order(1, yitem); xval = xsln->get_values(xia, xib); yval = ysln->get_values(yia, yib); for (i = 0; i < lin_np_tri[1]; i++) { double m = getmag(i); if (finite(m) && fabs(m) > max) max = fabs(m); } if (curved) { RefMap* refmap = xsln->get_refmap(); phx = refmap->get_phys_x(1); phy = refmap->get_phys_y(1); } idx = tri_indices[0]; } // obtain linearized values and coordinates at the midpoints double midval[4][3]; for (i = 0; i < 4; i++) { midval[i][0] = (verts[iv0][i] + verts[iv1][i])*0.5; midval[i][1] = (verts[iv1][i] + verts[iv2][i])*0.5; midval[i][2] = (verts[iv2][i] + verts[iv0][i])*0.5; }; // determine whether or not to split the element bool split; if (eps >= 1.0) { //if eps > 1, the user wants a fixed number of refinements (no adaptivity) split = (level < eps); } else { // calculate the approximate error of linearizing the normalized solution double err = fabs(getmag(idx[0]) - midmag(0)) + fabs(getmag(idx[1]) - midmag(1)) + fabs(getmag(idx[2]) - midmag(2)); split = !finite(err) || err > max*3*eps; // do the same for the curvature if (curved && !split) { double cerr = 0.0, cden = 0.0; // fixme for (i = 0; i < 3; i++) { cerr += fabs(phx[idx[i]] - midval[0][i]) + fabs(phy[idx[i]] - midval[1][i]); cden += fabs(phx[idx[i]]) + fabs(phy[idx[i]]); } split = (cerr > cden*2.5e-4); } // do extra tests at level 0, so as not to miss some functions with zero error at edge midpoints if (level == 0 && !split) { split = (fabs(getmag(8) - 0.5*(midmag(0) + midmag(1))) + fabs(getmag(9) - 0.5*(midmag(1) + midmag(2))) + fabs(getmag(4) - 0.5*(midmag(2) + midmag(0)))) > max*3*eps; } } // split the triangle if the error is too large, otherwise produce a linear triangle if (split) { if (curved) for (i = 0; i < 3; i++) { midval[0][i] = phx[idx[i]]; midval[1][i] = phy[idx[i]]; } // obtain mid-edge vertices int mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], getvalx(idx[0]), getvaly(idx[0])); int mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], getvalx(idx[1]), getvaly(idx[1])); int mid2 = get_vertex(iv2, iv0, midval[0][2], midval[1][2], getvalx(idx[2]), getvaly(idx[2])); // recur to sub-elements push_transform(0); process_triangle(iv0, mid0, mid2, level+1, xval, yval, phx, phy, tri_indices[1]); pop_transform(); push_transform(1); process_triangle(mid0, iv1, mid1, level+1, xval, yval, phx, phy, tri_indices[2]); pop_transform(); push_transform(2); process_triangle(mid2, mid1, iv2, level+1, xval, yval, phx, phy, tri_indices[3]); pop_transform(); push_transform(3); process_triangle(mid1, mid2, mid0, level+1, xval, yval, phx, phy, tri_indices[4]); pop_transform(); return; } } // no splitting: output a linear triangle add_triangle(iv0, iv1, iv2); }
void Vectorizer::process_quad(int iv0, int iv1, int iv2, int iv3, int level, scalar* xval, scalar* yval, double* phx, double* phy, int* idx) { // try not to split through the vertex with the largest value int a = (magvert(iv0) > magvert(iv1)) ? iv0 : iv1; int b = (magvert(iv2) > magvert(iv3)) ? iv2 : iv3; a = (magvert(a) > magvert(b)) ? a : b; int flip = (a == iv1 || a == iv3) ? 1 : 0; if (level < LIN_MAX_LEVEL) { int i; if (!(level & 1)) { // obtain solution values and physical element coordinates xsln->set_quad_order(1, xitem); ysln->set_quad_order(1, yitem); xval = xsln->get_values(xia, xib); yval = ysln->get_values(yia, yib); for (i = 0; i < lin_np_quad[1]; i++) { double m = getmag(i); if (finite(m) && fabs(m) > max) max = fabs(m); } if (curved) { RefMap* refmap = xsln->get_refmap(); phx = refmap->get_phys_x(1); phy = refmap->get_phys_y(1); } idx = quad_indices[0]; } // obtain linearized values and coordinates at the midpoints double midval[4][5]; for (i = 0; i < 4; i++) { midval[i][0] = (verts[iv0][i] + verts[iv1][i]) * 0.5; midval[i][1] = (verts[iv1][i] + verts[iv2][i]) * 0.5; midval[i][2] = (verts[iv2][i] + verts[iv3][i]) * 0.5; midval[i][3] = (verts[iv3][i] + verts[iv0][i]) * 0.5; midval[i][4] = (midval[i][0] + midval[i][2]) * 0.5; }; // determine whether or not to split the element bool split; if (eps >= 1.0) { //if eps > 1, the user wants a fixed number of refinements (no adaptivity) split = (level < eps); } else { // the value of the middle point is not the average of the four vertex values, since quad == 2 triangles midval[2][4] = flip ? (verts[iv0][2] + verts[iv2][2]) * 0.5 : (verts[iv1][2] + verts[iv3][2]) * 0.5; midval[3][4] = flip ? (verts[iv0][3] + verts[iv2][3]) * 0.5 : (verts[iv1][3] + verts[iv3][3]) * 0.5; // calculate the approximate error of linearizing the normalized solution double err = fabs(getmag(idx[0]) - midmag(0)) + fabs(getmag(idx[1]) - midmag(1)) + fabs(getmag(idx[2]) - midmag(2)) + fabs(getmag(idx[3]) - midmag(3)) + fabs(getmag(idx[4]) - midmag(4)); split = !finite(err) || err > max*4*eps; // do the same for the curvature if (curved && !split) { double cerr = 0.0, cden = 0.0; // fixme for (i = 0; i < 5; i++) { cerr += fabs(phx[idx[i]] - midval[0][i]) + fabs(phy[idx[i]] - midval[1][i]); cden += fabs(phx[idx[i]]) + fabs(phy[idx[i]]); } split = (cerr > cden*2.5e-4); } // do extra tests at level 0, so as not to miss functions with zero error at edge midpoints if (level == 0 && !split) { err = fabs(getmag(13) - 0.5*(midmag(0) + midmag(1))) + fabs(getmag(17) - 0.5*(midmag(1) + midmag(2))) + fabs(getmag(20) - 0.5*(midmag(2) + midmag(3))) + fabs(getmag(9) - 0.5*(midmag(3) + midmag(0))); split = !finite(err) || (err) > max*2*eps; //? } } // split the quad if the error is too large, otherwise produce two linear triangles if (split) { if (curved) for (i = 0; i < 5; i++) { midval[0][i] = phx[idx[i]]; midval[1][i] = phy[idx[i]]; } // obtain mid-edge and mid-element vertices int mid0 = get_vertex(iv0, iv1, midval[0][0], midval[1][0], getvalx(idx[0]), getvaly(idx[0])); int mid1 = get_vertex(iv1, iv2, midval[0][1], midval[1][1], getvalx(idx[1]), getvaly(idx[1])); int mid2 = get_vertex(iv2, iv3, midval[0][2], midval[1][2], getvalx(idx[2]), getvaly(idx[2])); int mid3 = get_vertex(iv3, iv0, midval[0][3], midval[1][3], getvalx(idx[3]), getvaly(idx[3])); int mid4 = get_vertex(mid0, mid2, midval[0][4], midval[1][4], getvalx(idx[4]), getvaly(idx[4])); // recur to sub-elements push_transform(0); process_quad(iv0, mid0, mid4, mid3, level+1, xval, yval, phx, phy, quad_indices[1]); pop_transform(); push_transform(1); process_quad(mid0, iv1, mid1, mid4, level+1, xval, yval, phx, phy, quad_indices[2]); pop_transform(); push_transform(2); process_quad(mid4, mid1, iv2, mid2, level+1, xval, yval, phx, phy, quad_indices[3]); pop_transform(); push_transform(3); process_quad(mid3, mid4, mid2, iv3, level+1, xval, yval, phx, phy, quad_indices[4]); pop_transform(); return; } } // output two linear triangles, if (!flip) { add_triangle(iv3, iv0, iv1); add_triangle(iv1, iv2, iv3); } else { add_triangle(iv0, iv1, iv2); add_triangle(iv2, iv3, iv0); } }