void dxfLineSegment::set(const dimeVec3f &p0, const dimeVec3f &p1, const dxfdouble startwidth, const dxfdouble endwidth, const dxfdouble thickness) { this->flags = 0; this->p[0] = p0; this->p[1] = p1; this->w[0] = startwidth; this->w[1] = endwidth; this->thickness = thickness; this->e = dimeVec3f(0,0,1) * thickness; this->dir = p[1]-p[0]; this->dir.normalize(); this->wdir = dimeVec3f(0,0,1).cross(dir); this->wdir.normalize(); }
// // private method which calculates the 4 resulting points for this // line segment (considering width). // void dxfLineSegment::calculate_v() { if (!(this->flags & FLAG_V_CALCULATED)) { this->v[0] = p[0]; this->v[1] = p[1]; dimeVec3f vec = dimeVec3f(0,0,1).cross(this->dir); vec.normalize(); this->v[2] = this->v[0] - vec*this->w[0]; this->v[3] = this->v[1] - vec*this->w[1]; this->v[0] += vec*this->w[0]; this->v[1] += vec*this->w[1]; this->flags |= FLAG_V_CALCULATED; } }
void convert_arc(const dimeEntity *entity, const dimeState *state, dxfLayerData *layerData, dxfConverter *converter) { dimeArc *arc = (dimeArc*) entity; dimeMatrix matrix; state->getMatrix(matrix); dimeVec3f e = arc->getExtrusionDir(); dxfdouble thickness = arc->getThickness(); if (e != dimeVec3f(0,0,1)) { dimeMatrix m; dimeEntity::generateUCS(e, m); matrix.multRight(m); } e = dimeVec3f(0,0,1); dimeVec3f center; arc->getCenter(center); dimeParam param; if (arc->getRecord(38, param)) { center[2] = param.double_data; } dxfdouble radius = arc->getRadius(); double end = arc->getEndAngle(); while (end < arc->getStartAngle()) { end += 360.0; } double delta = DXFDEG2RAD(end - arc->getStartAngle()); if (delta == 0.0) { #ifndef NDEBUG fprintf(stderr,"ARC with startAngle == endAngle!\n"); #endif end += 2*M_PI; delta = DXFDEG2RAD(end - arc->getStartAngle()); } int ARC_NUMPTS = converter->getNumSub(); if (ARC_NUMPTS <= 0) { // use maxerr ARC_NUMPTS = calc_num_sub(converter->getMaxerr(), radius); } // find the number of this ARC that fits inside 2PI int parts = (int) DXFABS((2*M_PI) / delta); // find # pts to use for arc // add one to avoid arcs with 0 line segments int numpts = ARC_NUMPTS / parts + 1; if (numpts > ARC_NUMPTS) numpts = ARC_NUMPTS; double inc = delta / numpts; double rad = DXFDEG2RAD(arc->getStartAngle()); int i; dimeVec3f v; dimeVec3f prev(center[0] + radius * cos(rad), center[1] + radius * sin(rad), center[2]); rad += inc; for (i = 1; i < numpts; i++) { v = dimeVec3f(center[0] + radius * cos(rad), center[1] + radius * sin(rad), center[2]); if (thickness == 0.0) { layerData->addLine(prev, v, &matrix); } else { layerData->addQuad(prev, v, v + e * thickness, prev + e * thickness, &matrix); } prev = v; rad += inc; } rad = DXFDEG2RAD(end); v = dimeVec3f(center[0] + radius * cos(rad), center[1] + radius * sin(rad), center[2]); if (thickness == 0.0) { layerData->addLine(prev, v, &matrix); } else { layerData->addQuad(prev, v, v + e * thickness, prev + e * thickness, &matrix); } }
void convert_lwpolyline(const dimeEntity *entity, const dimeState *state, dxfLayerData *layerData, dxfConverter *) { dimeLWPolyline *pline = (dimeLWPolyline*)entity; dimeMatrix matrix; state->getMatrix(matrix); dimeVec3f e = pline->getExtrusionDir(); dxfdouble thickness = pline->getThickness(); if (e != dimeVec3f(0,0,1)) { dimeMatrix m; dimeEntity::generateUCS(e, m); matrix.multRight(m); } e = dimeVec3f(0,0,1) * thickness; float elev = pline->getElevation(); if (!dime_finite(elev)) elev = 0.0f; int n = pline->getNumVertices(); if (n <= 0) return; dxfdouble constantWidth = pline->getConstantWidth(); const dxfdouble *x = pline->getXCoords(); const dxfdouble *y = pline->getYCoords(); const dxfdouble *sw = pline->getStartingWidths(); const dxfdouble *ew = pline->getEndWidths(); dimeVec3f v0, v1; #define SET_SEGMENT(s, i0, i1) \ s.set(dimeVec3f(x[i0], y[i0], elev), \ dimeVec3f(x[i1], y[i1], elev), \ sw ? sw[i0] : constantWidth, \ ew ? ew[i0] : constantWidth, \ thickness) dxfLineSegment segment, nextseg, prevseg; bool closed = pline->getFlags() & 1; int stop = closed ? n : n-1; int next, next2; for (int i = 0; i < stop; i++) { next = (i+1) % n; if (i == 0) { SET_SEGMENT(segment, i, next); if (closed) { SET_SEGMENT(prevseg, n-1, 0); } } next2 = (i+2) % n; SET_SEGMENT(nextseg, next, next2); segment.convert(i > 0 || closed ? &prevseg : NULL, i < (stop-1) ? &nextseg : NULL, layerData, &matrix); prevseg = segment; segment = nextseg; } #undef SET_SEGMENT }
void convert_ellipse(const dimeEntity *entity, const dimeState *state, dxfLayerData *layerData, dxfConverter *converter) { dimeEllipse *ellipse = (dimeEllipse*) entity; dimeMatrix matrix; state->getMatrix(matrix); dimeVec3f e = ellipse->getExtrusionDir(); dxfdouble thickness = ellipse->getThickness(); if (e != dimeVec3f(0,0,1)) { dimeMatrix m; dimeEntity::generateUCS(e, m); matrix.multRight(m); } e = dimeVec3f(0,0,1); dimeVec3f center = ellipse->getCenter(); // do some cross product magic to calculate minor axis dimeVec3f xaxis = ellipse->getMajorAxisEndpoint(); dimeParam param; if (ellipse->getRecord(38, param)) { center[2] = param.double_data; xaxis[2] = param.double_data; } dxfdouble xlen = (xaxis-center).length() * 0.5; xaxis.normalize(); dimeVec3f yaxis = dimeVec3f(0,0,1).cross(xaxis); yaxis.normalize(); dimeVec3f zaxis = xaxis.cross(yaxis); zaxis.normalize(); yaxis = zaxis.cross(xaxis); yaxis.normalize(); yaxis *= ellipse->getMinorMajorRatio() * xlen; xaxis *= xlen; dxfdouble numpts = (dxfdouble) converter->getNumSub(); if (numpts <= 0.0) { // use maxerr numpts = calc_num_sub(converter->getMaxerr(), xlen, xlen*ellipse->getMinorMajorRatio()); } dxfdouble rad = ellipse->getStartParam(); dxfdouble end = ellipse->getEndParam(); while (end <= rad) end += M_PI*2.0; dxfdouble size = (2*M_PI) / (end-rad); dxfdouble inc = (end-rad) / (numpts * size); int i; dimeVec3f v; dimeVec3f prev(center[0] + xaxis[0] * cos(rad) + yaxis[0] * sin(rad), center[1] + xaxis[1] * cos(rad) + yaxis[1] * sin(rad), center[2] + xaxis[2] * cos(rad) + yaxis[2] * sin(rad)); rad += inc; for (; rad < end; rad += inc) { v = dimeVec3f(center[0] + xaxis[0] * cos(rad) + yaxis[0] * sin(rad), center[1] + xaxis[1] * cos(rad) + yaxis[1] * sin(rad), center[2] + xaxis[2] * cos(rad) + yaxis[2] * sin(rad)); layerData->addLine(prev, v, &matrix); prev = v; rad += inc; } rad = end; v = dimeVec3f(center[0] + xaxis[0] * cos(rad) + yaxis[0] * sin(rad), center[1] + xaxis[1] * cos(rad) + yaxis[1] * sin(rad), center[2] + xaxis[2] * cos(rad) + yaxis[2] * sin(rad)); layerData->addLine(prev, v, &matrix); }