def write_embroidery_file(file_path, stitch_plan, svg): origin = get_origin(svg) pattern = libembroidery.embPattern_create() for color_block in stitch_plan: add_thread(pattern, make_thread(color_block.color)) for stitch in color_block: if stitch.stop and stitch is not color_block.last_stitch: # A STOP stitch that is not at the end of a color block # occurs when the user specified "STOP after". "STOP" is the # same thing as a color change, and the user will assign a # special color at the machine that tells it to pause after. # We need to add another copy of the same color here so that # the stitches after the STOP are still the same color. add_thread(pattern, make_thread(color_block.color)) flags = get_flags(stitch) libembroidery.embPattern_addStitchAbs(pattern, stitch.x - origin.x, stitch.y - origin.y, flags, 1) libembroidery.embPattern_addStitchAbs(pattern, stitch.x - origin.x, stitch.y - origin.y, libembroidery.END, 1) # convert from pixels to millimeters libembroidery.embPattern_scale(pattern, 1 / PIXELS_PER_MM) # SVG and embroidery disagree on the direction of the Y axis libembroidery.embPattern_flipVertical(pattern) libembroidery.embPattern_write(pattern, file_path)
def write_embroidery_file(file_path, stitches): # Embroidery machines don't care about our canvas size, so we relocate the # design to the origin. It might make sense to center it about the origin # instead. min_x = min(stitch.x for stitch in stitches) min_y = min(stitch.y for stitch in stitches) pattern = libembroidery.embPattern_create() last_color = None for stitch in stitches: if stitch.color != last_color: add_thread(pattern, make_thread(stitch.color)) last_color = stitch.color flags = get_flags(stitch) libembroidery.embPattern_addStitchAbs(pattern, stitch.x - min_x, stitch.y - min_y, flags, 1) libembroidery.embPattern_addStitchAbs(pattern, stitch.x - min_x, stitch.y - min_y, libembroidery.END, 1) # convert from pixels to millimeters libembroidery.embPattern_scale(pattern, 1 / PIXELS_PER_MM) # SVG and embroidery disagree on the direction of the Y axis libembroidery.embPattern_flipVertical(pattern) libembroidery.embPattern_write(pattern, file_path)
def write_embroidery_file(file_path, stitch_plan, svg): origin = get_origin(svg) pattern = libembroidery.embPattern_create() for color_block in stitch_plan: add_thread(pattern, make_thread(color_block.color)) for stitch in color_block: if stitch.stop: # This is the start of the extra color block added by the # "STOP after" handler (see stitch_plan/stop.py). Assign it # the same color. add_thread(pattern, make_thread(color_block.color)) flags = get_flags(stitch) libembroidery.embPattern_addStitchAbs(pattern, stitch.x - origin.x, stitch.y - origin.y, flags, 1) libembroidery.embPattern_addStitchAbs(pattern, stitch.x - origin.x, stitch.y - origin.y, libembroidery.END, 1) # convert from pixels to millimeters libembroidery.embPattern_scale(pattern, 1 / PIXELS_PER_MM) # SVG and embroidery disagree on the direction of the Y axis libembroidery.embPattern_flipVertical(pattern) libembroidery.embPattern_write(pattern, file_path)
def save(self, fileName): """ TOWRITE :param `fileName`: TOWRITE :type `fileName`: QString :rtype: bool """ qDebug("SaveObject save(%s)" % qPrintable(fileName)) # TODO: Before saving to a stitch only format, Embroidermodder needs # to calculate the optimal path to minimize jump stitches. Also # based upon which layer needs to be stitched first, # the path to the next object needs to be hidden beneath fills # that will come later. When finding the optimal path, we need # to take into account the color of the thread, as we do not want # to try to hide dark colored stitches beneath light colored fills. writeSuccessful = False # bool #TODO/PORT# int i self.formatType = embFormat_typeFromName(qPrintable(fileName)) if self.formatType == EMBFORMAT_UNSUPPORTED: return False ## pattern = 0 # EmbPattern* ## writer = 0 # EmbReaderWriter* pattern = embPattern_create() if not pattern: qDebug("Could not allocate memory for embroidery pattern") # Write. writer = embReaderWriter_getByFileName(qPrintable(fileName)) if not writer: qDebug("Unsupported write file type: %s" % qPrintable(fileName)) else: for item in self.gscene.items( ): # foreach(QGraphicsItem* item, gscene->items()) objType = item.data(OBJ_TYPE).toInt() # int if objType == OBJ_TYPE_ARC: self.addArc(pattern, item) elif objType == OBJ_TYPE_BLOCK: self.addBlock(pattern, item) elif objType == OBJ_TYPE_CIRCLE: self.addCircle(pattern, item) elif objType == OBJ_TYPE_DIMALIGNED: self.addDimAligned(pattern, item) elif objType == OBJ_TYPE_DIMANGULAR: self.addDimAngular(pattern, item) elif objType == OBJ_TYPE_DIMARCLENGTH: self.addDimArcLength(pattern, item) elif objType == OBJ_TYPE_DIMDIAMETER: self.addDimDiameter(pattern, item) elif objType == OBJ_TYPE_DIMLEADER: self.addDimLeader(pattern, item) elif objType == OBJ_TYPE_DIMLINEAR: self.addDimLinear(pattern, item) elif objType == OBJ_TYPE_DIMORDINATE: self.addDimOrdinate(pattern, item) elif objType == OBJ_TYPE_DIMRADIUS: self.addDimRadius(pattern, item) elif objType == OBJ_TYPE_ELLIPSE: self.addEllipse(pattern, item) elif objType == OBJ_TYPE_ELLIPSEARC: self.addEllipseArc(pattern, item) elif objType == OBJ_TYPE_GRID: self.addGrid(pattern, item) elif objType == OBJ_TYPE_HATCH: self.addHatch(pattern, item) elif objType == OBJ_TYPE_IMAGE: self.addImage(pattern, item) elif objType == OBJ_TYPE_INFINITELINE: self.addInfiniteLine(pattern, item) elif objType == OBJ_TYPE_LINE: self.addLine(pattern, item) elif objType == OBJ_TYPE_POINT: self.addPoint(pattern, item) elif objType == OBJ_TYPE_POLYGON: self.addPolygon(pattern, item) elif objType == OBJ_TYPE_POLYLINE: self.addPolyline(pattern, item) elif objType == OBJ_TYPE_RAY: self.addRay(pattern, item) elif objType == OBJ_TYPE_RECTANGLE: self.addRectangle(pattern, item) elif objType == OBJ_TYPE_SPLINE: self.addSpline(pattern, item) elif objType == OBJ_TYPE_TEXTMULTI: self.addTextMulti(pattern, item) elif objType == OBJ_TYPE_TEXTSINGLE: self.addTextSingle(pattern, item) # TODO: handle EMBFORMAT_STCHANDOBJ also if self.formatType == EMBFORMAT_STITCHONLY: embPattern_movePolylinesToStitchList( pattern) # TODO: handle all objects like this writeSuccessful = writer.writer(pattern, qPrintable(fileName)) if not writeSuccessful: qDebug("Writing file %s was unsuccessful" % qPrintable(fileName)) # TODO: check the embLog for errors and if any exist, report them. ## free(writer) #TODO/REMOVE# not needed in python ## embPattern_free(pattern) #TODO/REMOVE# not needed in python return writeSuccessful
def save(self, fileName): """ TOWRITE :param `fileName`: TOWRITE :type `fileName`: QString :rtype: bool """ qDebug("SaveObject save(%s)" % qPrintable(fileName)) # TODO: Before saving to a stitch only format, Embroidermodder needs # to calculate the optimal path to minimize jump stitches. Also # based upon which layer needs to be stitched first, # the path to the next object needs to be hidden beneath fills # that will come later. When finding the optimal path, we need # to take into account the color of the thread, as we do not want # to try to hide dark colored stitches beneath light colored fills. writeSuccessful = False # bool #TODO/PORT# int i self.formatType = embFormat_typeFromName(qPrintable(fileName)) if self.formatType == EMBFORMAT_UNSUPPORTED: return False ## pattern = 0 # EmbPattern* ## writer = 0 # EmbReaderWriter* pattern = embPattern_create() if not pattern: qDebug("Could not allocate memory for embroidery pattern") # Write. writer = embReaderWriter_getByFileName(qPrintable(fileName)) if not writer: qDebug("Unsupported write file type: %s" % qPrintable(fileName)) else: for item in self.gscene.items(): # foreach(QGraphicsItem* item, gscene->items()) objType = item.data(OBJ_TYPE).toInt() # int if objType == OBJ_TYPE_ARC: self.addArc(pattern, item) elif objType == OBJ_TYPE_BLOCK: self.addBlock(pattern, item) elif objType == OBJ_TYPE_CIRCLE: self.addCircle(pattern, item) elif objType == OBJ_TYPE_DIMALIGNED: self.addDimAligned(pattern, item) elif objType == OBJ_TYPE_DIMANGULAR: self.addDimAngular(pattern, item) elif objType == OBJ_TYPE_DIMARCLENGTH: self.addDimArcLength(pattern, item) elif objType == OBJ_TYPE_DIMDIAMETER: self.addDimDiameter(pattern, item) elif objType == OBJ_TYPE_DIMLEADER: self.addDimLeader(pattern, item) elif objType == OBJ_TYPE_DIMLINEAR: self.addDimLinear(pattern, item) elif objType == OBJ_TYPE_DIMORDINATE: self.addDimOrdinate(pattern, item) elif objType == OBJ_TYPE_DIMRADIUS: self.addDimRadius(pattern, item) elif objType == OBJ_TYPE_ELLIPSE: self.addEllipse(pattern, item) elif objType == OBJ_TYPE_ELLIPSEARC: self.addEllipseArc(pattern, item) elif objType == OBJ_TYPE_GRID: self.addGrid(pattern, item) elif objType == OBJ_TYPE_HATCH: self.addHatch(pattern, item) elif objType == OBJ_TYPE_IMAGE: self.addImage(pattern, item) elif objType == OBJ_TYPE_INFINITELINE: self.addInfiniteLine(pattern, item) elif objType == OBJ_TYPE_LINE: self.addLine(pattern, item) elif objType == OBJ_TYPE_POINT: self.addPoint(pattern, item) elif objType == OBJ_TYPE_POLYGON: self.addPolygon(pattern, item) elif objType == OBJ_TYPE_POLYLINE: self.addPolyline(pattern, item) elif objType == OBJ_TYPE_RAY: self.addRay(pattern, item) elif objType == OBJ_TYPE_RECTANGLE: self.addRectangle(pattern, item) elif objType == OBJ_TYPE_SPLINE: self.addSpline(pattern, item) elif objType == OBJ_TYPE_TEXTMULTI: self.addTextMulti(pattern, item) elif objType == OBJ_TYPE_TEXTSINGLE: self.addTextSingle(pattern, item) # TODO: handle EMBFORMAT_STCHANDOBJ also if self.formatType == EMBFORMAT_STITCHONLY: embPattern_movePolylinesToStitchList(pattern) # TODO: handle all objects like this writeSuccessful = writer.writer(pattern, qPrintable(fileName)) if not writeSuccessful: qDebug("Writing file %s was unsuccessful" % qPrintable(fileName)) # TODO: check the embLog for errors and if any exist, report them. ## free(writer) #TODO/REMOVE# not needed in python ## embPattern_free(pattern) #TODO/REMOVE# not needed in python return writeSuccessful
def loadFile(self, fileName): """ TOWRITE :param `fileName`: TOWRITE :type `fileName`: QString :rtype: bool """ qDebug("MdiWindow loadFile()") tmpColor = self.getCurrentColor() # QRgb file = QFile(fileName) if not file.open(QFile.ReadOnly | QFile.Text): QMessageBox.warning( self, self.tr("Error reading file"), self.tr("Cannot read file %s:\n%s." % (fileName, file.errorString())) ) return False QApplication.setOverrideCursor(Qt.WaitCursor) ext = self.fileExtension(fileName) # QString qDebug("ext: %s" % qPrintable(ext)) # Read p = embPattern_create() # EmbPattern* if not p: print("Could not allocate memory for embroidery pattern\n") exit(1) readSuccessful = 0 # int ## QString readError reader = embReaderWriter_getByFileName(qPrintable(fileName)) # EmbReaderWriter* if not reader: readSuccessful = 0 readError = "Unsupported read file type: " + fileName qDebug("Unsupported read file type: %s\n" % qPrintable(fileName)) else: readSuccessful = reader.reader(p, qPrintable(fileName)) if not readSuccessful: readError = "Reading file was unsuccessful: " + fileName qDebug("Reading file was unsuccessful: %s\n" % qPrintable(fileName)) ## free(reader) #TODO/REMOVE# not needed in python if not readSuccessful: QMessageBox.warning(self, self.tr("Error reading pattern"), self.tr(qPrintable(readError))) if readSuccessful: embPattern_moveStitchListToPolylines(p) # TODO: Test more stitchCount = embStitchList_count(p.stitchList) # int path = QPainterPath() if p.circleObjList: curCircleObj = p.circleObjList # EmbCircleObjectList* while curCircleObj: c = curCircleObj.circleObj.circle # EmbCircle thisColor = curCircleObj.circleObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) # NOTE: With natives, the Y+ is up and libembroidery Y+ is up, so inverting the Y is NOT needed. self.mainWin.nativeAddCircle(embCircle_centerX(c), embCircle_centerY(c), embCircle_radius(c), False, OBJ_RUBBER_OFF) # TODO: fill curCircleObj = curCircleObj.next if p.ellipseObjList: curEllipseObj = p.ellipseObjList # EmbEllipseObjectList* while curEllipseObj: e = curEllipseObj.ellipseObj.ellipse # EmbEllipse thisColor = curEllipseObj.ellipseObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) # NOTE: With natives, the Y+ is up and libembroidery Y+ is up, so inverting the Y is NOT needed. self.mainWin.nativeAddEllipse(embEllipse_centerX(e), embEllipse_centerY(e), embEllipse_width(e), embEllipse_height(e), 0, False, OBJ_RUBBER_OFF) # TODO: rotation and fill curEllipseObj = curEllipseObj.next if p.lineObjList: curLineObj = p.lineObjList # EmbLineObjectList* while curLineObj: li = curLineObj.lineObj.line # EmbLine thisColor = curLineObj.lineObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) # NOTE: With natives, the Y+ is up and libembroidery Y+ is up, so inverting the Y is NOT needed. self.mainWin.nativeAddLine(embLine_x1(li), embLine_y1(li), embLine_x2(li), embLine_y2(li), 0, OBJ_RUBBER_OFF) # TODO: rotation curLineObj = curLineObj.next if p.pathObjList: # TODO: This is unfinished. It needs more work curPathObjList = p.pathObjList # EmbPathObjectList* while curPathObjList: pathPath = QPainterPath() curPointList = curPathObjList.pathObj.pointList # EmbPointList* thisColor = curPathObjList.pathObj.color # EmbColor if curPointList: pp = curPointList.point # EmbPoint pathPath.moveTo(embPoint_x(pp), -embPoint_y(pp)) # NOTE: Qt Y+ is down and libembroidery Y+ is up, so inverting the Y is needed. curPointList = curPointList.next while curPointList: pp = curPointList.point # EmbPoint pathPath.lineTo(embPoint_x(pp), -embPoint_y(pp)) # NOTE: Qt Y+ is down and libembroidery Y+ is up, so inverting the Y is needed. curPointList = curPointList.next loadPen = QPen(qRgb(thisColor.r, thisColor.g, thisColor.b)) loadPen.setWidthF(0.35) loadPen.setCapStyle(Qt.RoundCap) loadPen.setJoinStyle(Qt.RoundJoin) obj = PathObject(0, 0, pathPath, loadPen.color().rgb()) # PathObject* obj.setObjectRubberMode(OBJ_RUBBER_OFF) self.gscene.addItem(obj) curPathObjList = curPathObjList.next if p.pointObjList: curPointObj = p.pointObjList # EmbPointObjectList* while curPointObj: po = curPointObj.pointObj.point # EmbPoint thisColor = curPointObj.pointObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) # NOTE: With natives, the Y+ is up and libembroidery Y+ is up, so inverting the Y is NOT needed. self.mainWin.nativeAddPoint(embPoint_x(po), embPoint_y(po)) curPointObj = curPointObj.next if p.polygonObjList: curPolygonObjList = p.polygonObjList # EmbPolygonObjectList* while curPolygonObjList: polygonPath = QPainterPath() firstPoint = False # bool startX = 0; startY = 0 # qreal x = 0; y = 0 # qreal curPointList = curPolygonObjList.polygonObj.pointList # EmbPointList* thisColor = curPolygonObjList.polygonObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) while curPointList: pp = curPointList.point # EmbPoint x = embPoint_x(pp) y = -embPoint_y(pp) # NOTE: Qt Y+ is down and libembroidery Y+ is up, so inverting the Y is needed. if firstPoint: polygonPath.lineTo(x,y) else: polygonPath.moveTo(x,y) firstPoint = True startX = x startY = y curPointList = curPointList.next polygonPath.translate(-startX, -startY) self.mainWin.nativeAddPolygon(startX, startY, polygonPath, OBJ_RUBBER_OFF) curPolygonObjList = curPolygonObjList.next # NOTE: Polylines should only contain NORMAL stitches. if p.polylineObjList: curPolylineObjList = p.polylineObjList # EmbPolylineObjectList* while curPolylineObjList: polylinePath = QPainterPath() firstPoint = False # bool startX = 0; startY = 0 # qreal x = 0; y = 0 # qreal curPointList = curPolylineObjList.polylineObj.pointList # EmbPointList* thisColor = curPolylineObjList.polylineObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) while curPointList: pp = curPointList.point # EmbPoint x = embPoint_x(pp) y = -embPoint_y(pp) # NOTE: Qt Y+ is down and libembroidery Y+ is up, so inverting the Y is needed. if firstPoint: polylinePath.lineTo(x,y) else: polylinePath.moveTo(x,y) firstPoint = True startX = x startY = y curPointList = curPointList.next polylinePath.translate(-startX, -startY) self.mainWin.nativeAddPolyline(startX, startY, polylinePath, OBJ_RUBBER_OFF) curPolylineObjList = curPolylineObjList.next if p.rectObjList: curRectObj = p.rectObjList # EmbRectObjectList* while curRectObj: r = curRectObj.rectObj.rect # EmbRect thisColor = curRectObj.rectObj.color # EmbColor self.setCurrentColor(qRgb(thisColor.r, thisColor.g, thisColor.b)) # NOTE: With natives, the Y+ is up and libembroidery Y+ is up, so inverting the Y is NOT needed. self.mainWin.nativeAddRectangle(embRect_x(r), embRect_y(r), embRect_width(r), embRect_height(r), 0, False, OBJ_RUBBER_OFF) # TODO: rotation and fill curRectObj = curRectObj.next self.setCurrentFile(fileName) self.mainWin.statusbar.showMessage("File loaded.") stitches = str(stitchCount) # QString: stitches.setNum(stitchCount) if self.mainWin.getSettingsGridLoadFromFile(): # TODO: Josh, provide me a hoop size and/or grid spacing from the pattern. pass QApplication.restoreOverrideCursor() else: #TODO/PORT# warning shown twice?! redundant ?! QApplication.restoreOverrideCursor() QMessageBox.warning(self, self.tr("Error reading pattern"), self.tr("Cannot read pattern")) ## embPattern_free(p) #TODO/REMOVE# not needed in python # Clear the undo stack so it is not possible to undo past this point. self.gview.getUndoStack().clear() self.setCurrentColor(tmpColor) fileWasLoaded = True self.mainWin.setUndoCleanIcon(fileWasLoaded) return fileWasLoaded