/*! Adds a stitch to the pattern (\a p) at the absolute position (\a x,\a y). Positive y is up. Units are in millimeters. */ void embPattern_addStitchAbs(EmbPattern* p, double x, double y, int flags, int isAutoColorIndex) { EmbStitch s; if(!p) { embLog_error("emb-pattern.c embPattern_addStitchAbs(), p argument is null\n"); return; } if(flags & END) { if(embStitchList_empty(p->stitchList)) return; /* Prevent unnecessary multiple END stitches */ if(p->lastStitch->stitch.flags & END) { embLog_error("emb-pattern.c embPattern_addStitchAbs(), found multiple END stitches\n"); return; } embPattern_fixColorCount(p); /* HideStitchesOverLength(127); TODO: fix or remove this */ } if(flags & STOP) { if(embStitchList_empty(p->stitchList)) return; if(isAutoColorIndex) p->currentColorIndex++; } /* NOTE: If the stitchList is empty, we will create it before adding stitches to it. The first coordinate will be the HOME position. */ if(embStitchList_empty(p->stitchList)) { /* NOTE: Always HOME the machine before starting any stitching */ EmbPoint home = embSettings_home(&(p->settings)); EmbStitch h; h.xx = home.xx; h.yy = home.yy; h.flags = JUMP; h.color = p->currentColorIndex; p->stitchList = p->lastStitch = embStitchList_create(h); } s.xx = x; s.yy = y; s.flags = flags; s.color = p->currentColorIndex; #ifdef ARDUINO inoEvent_addStitchAbs(p, s.xx, s.yy, s.flags, s.color); #else /* ARDUINO */ p->lastStitch = embStitchList_add(p->lastStitch, s); #endif /* ARDUINO */ p->lastX = s.xx; p->lastY = s.yy; }
/* Adds a stitch at the relative position (dx,dy) to the previous stitch. Positive y is up. Units are in millimeters. */ void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex) { /* TODO: pointer safety */ double x,y; if(!embStitchList_empty(p->stitchList)) { x = p->lastX + dx; y = p->lastY + dy; } else { /* the list is empty so assume starting location is 0,0 */ x = dx; y = dy; } embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex); }
/* Adds a stitch at the relative position (dx,dy) to the previous stitch. Positive y is up. Units are in millimeters. */ void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex) { double x,y; if(!p) { embLog_error("emb-pattern.c embPattern_addStitchRel(), p argument is null\n"); return; } if(!embStitchList_empty(p->stitchList)) { x = p->lastX + dx; y = p->lastY + dy; } else { /* the list is empty so assume starting location is 0,0 */ x = dx; y = dy; } embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex); }
/*! Adds a stitch to the pattern (\a p) at the relative position (\a dx,\a dy) to the previous stitch. Positive y is up. Units are in millimeters. */ void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex) { double x,y; if(!p) { embLog_error("emb-pattern.c embPattern_addStitchRel(), p argument is null\n"); return; } if(!embStitchList_empty(p->stitchList)) { x = p->lastX + dx; y = p->lastY + dy; } else { /* NOTE: The stitchList is empty, so add it to the HOME position. The embStitchList_create function will ensure the first coordinate is at the HOME position. */ EmbPoint home = embSettings_home(&(p->settings)); x = home.xx + dx; y = home.yy + dy; } embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex); }
/* Adds a stitch at the absolute position (x,y). Positive y is up. Units are in millimeters. */ void embPattern_addStitchAbs(EmbPattern* p, double x, double y, int flags, int isAutoColorIndex) { EmbStitch s; if(!p) { embLog_error("emb-pattern.c embPattern_addStitchAbs(), p argument is null\n"); return; } if(flags & END) { embPattern_fixColorCount(p); /* HideStitchesOverLength(127); TODO: fix or remove this */ } if((flags & STOP) && embStitchList_empty(p->stitchList)) return; if((flags & STOP) && isAutoColorIndex) { p->currentColorIndex++; } s.xx = x; s.yy = y; s.flags = flags; s.color = p->currentColorIndex; if(!(p->stitchList)) { p->stitchList = (EmbStitchList*)malloc(sizeof(EmbStitchList)); if(!p->stitchList) { embLog_error("emb-pattern.c embPattern_addStitchAbs(), cannot allocate memory for p->stitchList\n"); return; } p->stitchList->stitch = s; p->stitchList->next = 0; p->lastStitch = p->stitchList; } else { embStitchList_add(p->lastStitch, s); p->lastStitch = p->lastStitch->next; } p->lastX = s.xx; p->lastY = s.yy; }
/* Adds a stitch at the absolute position (x,y). Positive y is up. Units are in millimeters. */ void embPattern_addStitchAbs(EmbPattern* p, double x, double y, int flags, int isAutoColorIndex) { /* TODO: pointer safety */ EmbStitch s; if(flags & END) { embPattern_fixColorCount(p); /* HideStitchesOverLength(127); TODO: fix or remove this */ } if((flags & STOP) && embStitchList_empty(p->stitchList)) return; if((flags & STOP) && isAutoColorIndex) { p->currentColorIndex++; } s.xx = x; s.yy = y; s.flags = flags; s.color = p->currentColorIndex; if(!(p->stitchList)) { p->stitchList = (EmbStitchList*)malloc(sizeof(EmbStitchList)); /* TODO: malloc fail error */ p->stitchList->stitch = s; p->stitchList->next = 0; p->lastStitch = p->stitchList; } else { embStitchList_add(p->lastStitch, s); p->lastStitch = p->lastStitch->next; } p->lastX = s.xx; p->lastY = s.yy; }
static void xxxEncodeDesign(FILE* file, EmbPattern* p) { double thisX = 0.0f; double thisY = 0.0f; EmbStitchList* stitches; if(!embStitchList_empty(p->stitchList)) { thisX = (float)p->stitchList->stitch.xx; thisY = (float)p->stitchList->stitch.yy; } stitches = p->stitchList; while(stitches) { EmbStitch s = stitches->stitch; double deltaX, deltaY; double previousX = thisX; double previousY = thisY; thisX = s.xx; thisY = s.yy; deltaX = thisX - previousX; deltaY = thisY - previousY; if(s.flags & STOP) { xxxEncodeStop(file, s); } else if(s.flags & END) { } else { xxxEncodeStitch(file, deltaX * 10.0f, deltaY * 10.0f, s.flags); } stitches = stitches->next; } }
/* Calculates a rectangle that encapsulates all stitches and objects in the pattern. */ EmbRect embPattern_calcBoundingBox(EmbPattern* p) { EmbStitchList* pointer = 0; EmbRect boundingRect; EmbStitch pt; EmbArcObjectList* aObjList = 0; EmbArc arc; EmbCircleObjectList* cObjList = 0; EmbCircle circle; EmbEllipseObjectList* eObjList = 0; EmbEllipse ellipse; EmbLineObjectList* liObjList = 0; EmbLine line; EmbPointObjectList* pObjList = 0; EmbPoint point; EmbPolygonObjectList* pogObjList = 0; EmbPointList* pogPointList = 0; EmbPoint pogPoint; EmbPolylineObjectList* polObjList = 0; EmbPointList* polPointList = 0; EmbPoint polPoint; EmbRectObjectList* rObjList = 0; EmbRect rect; EmbSplineObjectList* sObjList = 0; EmbBezier bezier; if(!p) { embLog_error("emb-pattern.c embPattern_calcBoundingBox(), p argument is null\n"); return boundingRect; } /* Calculate the bounding rectangle. It's needed for smart repainting. */ /* TODO: Come back and optimize this mess so that after going thru all objects and stitches, if the rectangle isn't reasonable, then return a default rect */ if(embStitchList_empty(p->stitchList) && embArcObjectList_empty(p->arcObjList) && embCircleObjectList_empty(p->circleObjList) && embEllipseObjectList_empty(p->ellipseObjList) && embLineObjectList_empty(p->lineObjList) && embPointObjectList_empty(p->pointObjList) && embPolygonObjectList_empty(p->polygonObjList) && embPolylineObjectList_empty(p->polylineObjList) && embRectObjectList_empty(p->rectObjList) && embSplineObjectList_empty(p->splineObjList)) { boundingRect.top = 0.0; boundingRect.left = 0.0; boundingRect.bottom = 1.0; boundingRect.right = 1.0; return boundingRect; } boundingRect.left = 99999.0; boundingRect.top = 99999.0; boundingRect.right = -99999.0; boundingRect.bottom = -99999.0; pointer = p->stitchList; while(pointer) { /* If the point lies outside of the accumulated bounding * rectangle, then inflate the bounding rect to include it. */ pt = pointer->stitch; if(!(pt.flags & TRIM)) { boundingRect.left = (double)min(boundingRect.left, pt.xx); boundingRect.top = (double)min(boundingRect.top, pt.yy); boundingRect.right = (double)max(boundingRect.right, pt.xx); boundingRect.bottom = (double)max(boundingRect.bottom, pt.yy); } pointer = pointer->next; } aObjList = p->arcObjList; while(aObjList) { arc = aObjList->arcObj.arc; /* TODO: embPattern_calcBoundingBox for arcs */ aObjList = aObjList->next; } cObjList = p->circleObjList; while(cObjList) { circle = cObjList->circleObj.circle; boundingRect.left = (double)min(boundingRect.left, circle.centerX - circle.radius); boundingRect.top = (double)min(boundingRect.top, circle.centerY - circle.radius); boundingRect.right = (double)max(boundingRect.right, circle.centerX + circle.radius); boundingRect.bottom = (double)max(boundingRect.bottom, circle.centerY + circle.radius); cObjList = cObjList->next; } eObjList = p->ellipseObjList; while(eObjList) { ellipse = eObjList->ellipseObj.ellipse; /* TODO: embPattern_calcBoundingBox for ellipses */ eObjList = eObjList->next; } liObjList = p->lineObjList; while(liObjList) { line = liObjList->lineObj.line; /* TODO: embPattern_calcBoundingBox for lines */ liObjList = liObjList->next; } pObjList = p->pointObjList; while(pObjList) { point = pObjList->pointObj.point; /* TODO: embPattern_calcBoundingBox for points */ pObjList = pObjList->next; } pogObjList = p->polygonObjList; while(pogObjList) { pogPointList = pogObjList->polygonObj->pointList; while(pogPointList) { pogPoint = pogPointList->point; /* TODO: embPattern_calcBoundingBox for polygons */ pogPointList = pogPointList->next; } pogObjList = pogObjList->next; } polObjList = p->polylineObjList; while(polObjList) { polPointList = polObjList->polylineObj->pointList; while(polPointList) { polPoint = polPointList->point; /* TODO: embPattern_calcBoundingBox for polylines */ polPointList = polPointList->next; } polObjList = polObjList->next; } rObjList = p->rectObjList; while(rObjList) { rect = rObjList->rectObj.rect; /* TODO: embPattern_calcBoundingBox for rectangles */ rObjList = rObjList->next; } sObjList = p->splineObjList; while(sObjList) { bezier = sObjList->splineObj.bezier; /* TODO: embPattern_calcBoundingBox for splines */ sObjList = sObjList->next; } return boundingRect; }