There is no way to change the line widths when using software rendering. The documentation (http://www.research.ibm.com/dx/docs/legacyhtml/pages/refgu098.htm#HDROPTIONS) says that Display and Image should be influenced by the option "line width". However, this is only the case if Image uses hardware rendering mode. When using software rendering (execute dx/samples/programs/FatLines.net in OpenDX 4.1.0, select Options -> Rendering Options -> Rendering Mode Software), lines have always width 1. As you can't use hardware rendering with Render, there is no way to export images with thick lines to a printable format (except saving the image in Image while hardware rendering is enabled). So it's unfortunately not possible to generate printable high quality output because with high resolutions lines become too thinn. The patch below implements variable width lines in software rendering mode. It simply draws lines more than once with a small parallel displacement. Moritz diff -C3 dx-4.1.0.orig/src/exec/libdx/line.c dx-4.1.0/src/exec/libdx/line.c *** dx-4.1.0.orig/src/exec/libdx/line.c Wed Jul 14 14:57:09 1999 --- dx-4.1.0/src/exec/libdx/line.c Fri Aug 11 23:49:02 2000 *************** *** 11,16 **** --- 11,17 ---- #include <dx/dx.h> + #include <math.h> #include "render.h" /* *************** *** 144,154 **** { Point p, p1; float length, d, dr, dg, db, r, g, b, z; ! float dx, dy, dz, dop, obar, a; int maj, dpix_dmaj, dy_dmaj, dx_dmaj; int min, dpix_dmin, dy_dmin, dx_dmin; int i, nmaj, x, y, frac; int width = buf->width, height = buf->height; /* positions */ p = xf->positions[l.p]; --- 145,156 ---- { Point p, p1; float length, d, dr, dg, db, r, g, b, z; ! float dx, dy, dz, dop, obar, a, norm, offset, ddx, ddy; int maj, dpix_dmaj, dy_dmaj, dx_dmaj; int min, dpix_dmin, dy_dmin, dx_dmin; int i, nmaj, x, y, frac; int width = buf->width, height = buf->height; + int linenr, nlines; /* positions */ p = xf->positions[l.p]; *************** *** 166,298 **** } p.z = (float)-1.0/p.z; p.x *= p.z; p.y *= p.z; p1.z = (float)-1.0/p1.z; p1.x *= p1.z; p1.y *= p1.z; - } - /* quick check */ - if ((p.x<buf->min.x-.5 && p1.x<buf->min.x-.5) || - (p.y<buf->min.y-.5 && p1.y<buf->min.y-.5) || - (p.x>buf->max.x+.5 && p1.x>buf->max.x+.5) || - (p.y>buf->max.y+.5 && p1.y>buf->max.y+.5)) - return OK; - - #if 0 - /* overflow check - XXX check performance impact */ - if (p.x>=MAXC || p.x<=-MAXC || p.y>=MAXC || p.y<=-MAXC - || p1.x>=MAXC || p1.x<=-MAXC || p1.y>=MAXC || p1.y<=-MAXC) - DXErrorReturn(ERROR_BAD_PARAMETER, "camera causes numerical overflow"); - #endif - /* deltas */ dx = p1.x - p.x; dy = p1.y - p.y; ! ! /* octant-dependent setup */ ! if (ABS(dy) < ABS(dx)) { ! ! XYCLIP(p,p1, c,c1, o,o1, x,y, dx, dy, <, buf->min.x-.5); ! XYCLIP(p1,p, c1,c, o1,o, x,y, -dx,-dy, <, buf->min.x-.5); ! XYCLIP(p,p1, c,c1, o,o1, x,y, dx, dy, >, buf->max.x+.5); ! XYCLIP(p1,p, c1,c, o1,o, x,y, -dx,-dy, >, buf->max.x+.5); ! dx = p1.x - p.x; ! dy = p1.y - p.y; ! ! x = ROUND(p.x); ! d = x - p.x; ! a = p.y + (dx? dy/dx*d : 0); ! y = ROUND(a); ! ! if (dx>0) dx_dmaj = 1, length = dx, nmaj = ROUND(p1.x) - x; ! else dx_dmaj = -1, length = -dx, nmaj = x - ROUND(p1.x); ! maj = length * SCALE; ! frac = (a - y) * maj; ! if (dy>0) dy_dmin = 1, min = dy*SCALE, frac = maj/2 - frac; ! else dy_dmin = -1, min = -dy*SCALE, frac = maj/2 + frac; ! dx_dmin = 0; ! dy_dmaj = 0; ! } else { ! XYCLIP(p,p1, c,c1, o,o1, y,x, dy, dx, <, buf->min.y-.5); ! XYCLIP(p1,p, c1,c, o1,o, y,x, -dy,-dx, <, buf->min.y-.5); ! XYCLIP(p,p1, c,c1, o,o1, y,x, dy, dx, >, buf->max.y+.5); ! XYCLIP(p1,p, c1,c, o1,o, y,x, -dy,-dx, >, buf->max.y+.5); ! dx = p1.x - p.x; ! dy = p1.y - p.y; ! ! y = ROUND(p.y); ! d = y - p.y; ! a = p.x + (dy? dx/dy*d : 0); ! x = ROUND(a); ! ! if (dy>0) dy_dmaj = 1, length = dy, nmaj = ROUND(p1.y) - y; ! else dy_dmaj = -1, length = -dy, nmaj = y - ROUND(p1.y); ! maj = length * SCALE; ! frac = (a - x) * maj; ! if (dx>0) dx_dmin = 1, min = dx*SCALE, frac = maj/2 - frac; ! else dx_dmin = -1, min = -dx*SCALE, frac = maj/2 + frac; ! dy_dmin = 0; ! dx_dmaj = 0; ! length = ABS(dy); ! } ! /* delta z, color, taking care not to divide by 0 */ ! dz = length? (p1.z - p.z) / length : 0.0; ! if (! flat) ! { ! dop = length? (o1 - o ) / length : 0.0; ! dr = length? (c1.r - c.r) / length : 0.0; ! dg = length? (c1.g - c.g) / length : 0.0; ! db = length? (c1.b - c.b) / length : 0.0; ! r = c.r + dr * d; ! g = c.g + dg * d; ! b = c.b + db * d; ! o += dop * d; ! } ! else ! { ! r = c.r; ! g = c.g; ! b = c.b; ! } ! z = p.z + dz * d; ! /* delta pix */ ! dpix_dmaj = dy_dmaj*width + dx_dmaj; ! dpix_dmin = dy_dmin*width + dx_dmin; ! ! /* offset */ ! x += buf->ox; ! y += buf->oy; ! ! if (buf->pix_type==pix_fast) { ! struct fast *pix = buf->u.fast + y*width + x; ! ASSERT(!clip); ! if (flat) ! if (xf->opacities) ! LOOP(1,1, NOCLIPZ) ! else ! LOOP(1,0, NOCLIPZ) ! else ! if (xf->opacities) ! LOOP(0,1, NOCLIPZ) ! else ! LOOP(0,0, NOCLIPZ) ! } else if (buf->pix_type==pix_big) { ! struct big *pix = buf->u.big + y*width + x; ! if (flat) ! if (xf->opacities) ! CLIP(1,1, TRANSCLIPZ) ! else ! CLIP(1,0, CLIPZ) else ! if (xf->opacities) ! CLIP(0,1, TRANSCLIPZ) else ! CLIP(0,0, CLIPZ) } return OK; --- 168,331 ---- } p.z = (float)-1.0/p.z; p.x *= p.z; p.y *= p.z; p1.z = (float)-1.0/p1.z; p1.x *= p1.z; p1.y *= p1.z; } /* deltas */ dx = p1.x - p.x; dy = p1.y - p.y; ! ! /* set up variables for line width */ ! nlines=ROUND(xf->tile.linewidth); ! if (nlines==0) { ! nlines=1; ! } ! norm=sqrt(dx*dx + dy*dy); ! offset=xf->tile.linewidth/2.; ! if (nlines==1) { ! offset=0; ! } ! if (norm!=0) { ! ddx = -0.5 * dy/norm; ! ddy = 0.5 * dx/norm; } else { + ddx = 0; + ddy = 0; + } + p.x -= offset * ddx; + p1.x -= offset * ddx; + p.y -= offset * ddy; + p1.y -= offset * ddy; + + for (linenr=0; linenr<nlines; linenr++) { + + /* generate parallel lines to account for line width */ + p.x += ddx; + p1.x += ddx; + p.y += ddy; + p1.y += ddy; + + /* quick check */ + if ((p.x<buf->min.x-.5 && p1.x<buf->min.x-.5) || + (p.y<buf->min.y-.5 && p1.y<buf->min.y-.5) || + (p.x>buf->max.x+.5 && p1.x>buf->max.x+.5) || + (p.y>buf->max.y+.5 && p1.y>buf->max.y+.5)) + return OK; ! #if 0 ! /* overflow check - XXX check performance impact */ ! if (p.x>=MAXC || p.x<=-MAXC || p.y>=MAXC || p.y<=-MAXC ! || p1.x>=MAXC || p1.x<=-MAXC || p1.y>=MAXC || p1.y<=-MAXC) ! DXErrorReturn(ERROR_BAD_PARAMETER, "camera causes numerical overflow"); ! #endif ! /* octant-dependent setup */ ! if (ABS(dy) < ABS(dx)) { ! XYCLIP(p,p1, c,c1, o,o1, x,y, dx, dy, <, buf->min.x-.5); ! XYCLIP(p1,p, c1,c, o1,o, x,y, -dx,-dy, <, buf->min.x-.5); ! XYCLIP(p,p1, c,c1, o,o1, x,y, dx, dy, >, buf->max.x+.5); ! XYCLIP(p1,p, c1,c, o1,o, x,y, -dx,-dy, >, buf->max.x+.5); ! dx = p1.x - p.x; ! dy = p1.y - p.y; ! ! x = ROUND(p.x); ! d = x - p.x; ! a = p.y + (dx? dy/dx*d : 0); ! y = ROUND(a); ! ! if (dx>0) dx_dmaj = 1, length = dx, nmaj = ROUND(p1.x) - x; ! else dx_dmaj = -1, length = -dx, nmaj = x - ROUND(p1.x); ! maj = length * SCALE; ! frac = (a - y) * maj; ! if (dy>0) dy_dmin = 1, min = dy*SCALE, frac = maj/2 - frac; ! else dy_dmin = -1, min = -dy*SCALE, frac = maj/2 + frac; ! dx_dmin = 0; ! dy_dmaj = 0; ! ! } else { ! ! XYCLIP(p,p1, c,c1, o,o1, y,x, dy, dx, <, buf->min.y-.5); ! XYCLIP(p1,p, c1,c, o1,o, y,x, -dy,-dx, <, buf->min.y-.5); ! XYCLIP(p,p1, c,c1, o,o1, y,x, dy, dx, >, buf->max.y+.5); ! XYCLIP(p1,p, c1,c, o1,o, y,x, -dy,-dx, >, buf->max.y+.5); ! dx = p1.x - p.x; ! dy = p1.y - p.y; ! ! y = ROUND(p.y); ! d = y - p.y; ! a = p.x + (dy? dx/dy*d : 0); ! x = ROUND(a); ! ! if (dy>0) dy_dmaj = 1, length = dy, nmaj = ROUND(p1.y) - y; ! else dy_dmaj = -1, length = -dy, nmaj = y - ROUND(p1.y); ! maj = length * SCALE; ! frac = (a - x) * maj; ! if (dx>0) dx_dmin = 1, min = dx*SCALE, frac = maj/2 - frac; ! else dx_dmin = -1, min = -dx*SCALE, frac = maj/2 + frac; ! dy_dmin = 0; ! dx_dmaj = 0; ! length = ABS(dy); ! } ! /* delta z, color, taking care not to divide by 0 */ ! dz = length? (p1.z - p.z) / length : 0.0; ! if (! flat) ! { ! dop = length? (o1 - o ) / length : 0.0; ! dr = length? (c1.r - c.r) / length : 0.0; ! dg = length? (c1.g - c.g) / length : 0.0; ! db = length? (c1.b - c.b) / length : 0.0; ! r = c.r + dr * d; ! g = c.g + dg * d; ! b = c.b + db * d; ! o += dop * d; ! } else ! { ! r = c.r; ! g = c.g; ! b = c.b; ! } ! ! z = p.z + dz * d; ! ! /* delta pix */ ! dpix_dmaj = dy_dmaj*width + dx_dmaj; ! dpix_dmin = dy_dmin*width + dx_dmin; ! ! /* offset */ ! x += buf->ox; ! y += buf->oy; ! ! if (buf->pix_type==pix_fast) { ! struct fast *pix = buf->u.fast + y*width + x; ! ASSERT(!clip); ! if (flat) ! if (xf->opacities) ! LOOP(1,1, NOCLIPZ) ! else ! LOOP(1,0, NOCLIPZ) ! else ! if (xf->opacities) ! LOOP(0,1, NOCLIPZ) ! else ! LOOP(0,0, NOCLIPZ) ! } else if (buf->pix_type==pix_big) { ! struct big *pix = buf->u.big + y*width + x; ! if (flat) ! if (xf->opacities) ! CLIP(1,1, TRANSCLIPZ) ! else ! CLIP(1,0, CLIPZ) else ! if (xf->opacities) ! CLIP(0,1, TRANSCLIPZ) ! else ! CLIP(0,0, CLIPZ) ! } ! } return OK; diff -C3 dx-4.1.0.orig/src/exec/libdx/paint.c dx-4.1.0/src/exec/libdx/paint.c *** dx-4.1.0.orig/src/exec/libdx/paint.c Mon May 10 17:45:45 1999 --- dx-4.1.0/src/exec/libdx/paint.c Fri Aug 11 22:15:48 2000 *************** *** 49,54 **** --- 49,56 ---- if (!_dxf_approx(o, &new->approx)) return ERROR; + PARAMETER(linewidth,"line width",float,DXExtractFloat); + return OK; } diff -C3 dx-4.1.0.orig/src/exec/libdx/render.h dx-4.1.0/src/exec/libdx/render.h *** dx-4.1.0.orig/src/exec/libdx/render.h Thu Jun 3 15:32:48 1999 --- dx-4.1.0/src/exec/libdx/render.h Fri Aug 11 22:15:30 2000 *************** *** 47,52 **** --- 47,53 ---- approx_dots, /* dots */ approx_box /* box */ } approx; + float linewidth; /* line width */ }; Error _dxf_approx(Object o, enum approx *approx);
