Skip to content

Commit

Permalink
Add a printer profile option to allow centered origin on rectangular
Browse files Browse the repository at this point in the history
beds

Some printers have (0, 0) at the center of the bed.  Circular beds
commonly, but also some rectangular beds.
  • Loading branch information
markwal committed Apr 15, 2015
1 parent e8c085b commit fbe50e3
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 8 deletions.
7 changes: 7 additions & 0 deletions src/octoprint/printer/profile.py
Expand Up @@ -72,6 +72,11 @@ class PrinterProfileManager(object):
* - ``volume.formFactor``
- ``string``
- Form factor of the print bed, either ``rectangular`` or ``circular``
* - ``centeredOrigin``
- ``bool``
- Whether the printer's origin is in the center of the bed, otherwise

This comment has been minimized.

Copy link
@foosel

foosel Apr 15, 2015

Something's odd with the formatting here. I guess you wanted:

* - ``centeredOrigin``
  - ``bool``
  - Whether the printer's origin is in the center of the bed, otherwise the origin is assumed to be the lower left and all valid coordinates positive.

I'd rather move the option to volume.origin though, make it a string that accepts center, lowerleft and (later) x,y values (with center staying the default for a circular form factor).

- the origin is assumed to be the lower left and all valid coordinates
- positive.
* - ``heatedBed``
- ``bool``
- Whether the printer has a heated bed (``True``) or not (``False``)
Expand Down Expand Up @@ -140,6 +145,7 @@ class PrinterProfileManager(object):
formFactor = BedTypes.RECTANGULAR,
),
heatedBed = False,
centeredOrigin = False,
extruder=dict(
count = 1,
offsets = [
Expand Down Expand Up @@ -291,6 +297,7 @@ def _load_from_path(self, path):
import yaml
with open(path) as f:
profile = yaml.safe_load(f)
profile = dict_merge(self._load_default(), profile)
profile = self._ensure_valid_profile(profile)
if not profile:
self._logger.warn("Invalid profile: %s" % path)
Expand Down
15 changes: 10 additions & 5 deletions src/octoprint/static/gcodeviewer/js/renderer.js
Expand Up @@ -266,6 +266,11 @@ GCODE.renderer = (function(){
y: -1 * renderOptions["bed"]["y"] * zoomFactor
};

if (renderOptions["bed"]["centeredOrigin"]) {
origin.x -= width / 2;
origin.y += height / 2;
}

ctx.beginPath();
ctx.strokeStyle = renderOptions["colorGrid"];
ctx.fillStyle = "#ffffff";
Expand All @@ -281,15 +286,15 @@ GCODE.renderer = (function(){

ctx.beginPath();
for (i = 0; i <= renderOptions["bed"]["x"]; i += gridStep) {
ctx.moveTo(i * zoomFactor, 0);
ctx.lineTo(i * zoomFactor, -1 * renderOptions["bed"]["y"] * zoomFactor);
ctx.moveTo(origin.x + i * zoomFactor, origin.y);
ctx.lineTo(origin.x + i * zoomFactor, origin.y + height);
}
ctx.stroke();

ctx.beginPath();
for (i = 0; i <= renderOptions["bed"]["y"]; i += gridStep) {
ctx.moveTo(0, -1 * i * zoomFactor);
ctx.lineTo(renderOptions["bed"]["x"] * zoomFactor, -1 * i * zoomFactor);
ctx.moveTo(origin.x, origin.y + i * zoomFactor);
ctx.lineTo(origin.x + width, origin.y + i * zoomFactor);
}
ctx.stroke();
};
Expand Down Expand Up @@ -496,7 +501,7 @@ GCODE.renderer = (function(){
offsetModelY = -1 * (renderOptions["bed"]["y"] / 2 - (mdlInfo.min.y + mdlInfo.modelSize.y / 2)) * zoomFactor;
offsetBedX = -1 * (renderOptions["bed"]["x"] / 2 - (mdlInfo.min.x + mdlInfo.modelSize.x / 2)) * zoomFactor;
offsetBedY = (renderOptions["bed"]["y"] / 2 - (mdlInfo.min.y + mdlInfo.modelSize.y / 2)) * zoomFactor;
} else if (renderOptions["bed"]["circular"]) {
} else if (renderOptions["bed"]["circular"] || renderOptions["bed"]["centeredOrigin"]) {
canvasCenter = ctx.transformedPoint(canvas.width / 2, canvas.height / 2);
offsetModelX = canvasCenter.x;
offsetModelY = canvasCenter.y;
Expand Down
9 changes: 6 additions & 3 deletions src/octoprint/static/js/app/viewmodels/gcode.js
Expand Up @@ -137,22 +137,25 @@ $(function() {
}

if (currentProfileData && currentProfileData.volume && currentProfileData.volume.formFactor() && currentProfileData.volume.width() && currentProfileData.volume.depth()) {
var x = undefined, y = undefined, r = undefined, circular = false;
var x = undefined, y = undefined, r = undefined, circular = false, centeredOrigin = false;

var formFactor = currentProfileData.volume.formFactor();
if (formFactor == "circular") {
r = currentProfileData.volume.width() / 2;
circular = true;
centeredOrigin = true;
} else {
x = currentProfileData.volume.width();
y = currentProfileData.volume.depth();
centeredOrigin = currentProfileData.hasOwnProperty("centeredOrigin") && currentProfileData.centeredOrigin();
}

return {
x: x,
y: y,
r: r,
circular: circular
circular: circular,
centeredOrigin: centeredOrigin
};
} else {
return undefined;
Expand Down Expand Up @@ -507,4 +510,4 @@ $(function() {
["loginStateViewModel", "settingsViewModel"],
"#gcode"
]);
});
});
3 changes: 3 additions & 0 deletions src/octoprint/static/js/app/viewmodels/printerprofiles.js
Expand Up @@ -68,6 +68,7 @@ $(function() {
self.editorVolumeFormFactor = ko.observable();

self.editorHeatedBed = ko.observable();
self.editorCenteredOrigin = ko.observable();

self.editorNozzleDiameter = ko.observable();
self.editorExtruders = ko.observable();
Expand Down Expand Up @@ -284,6 +285,7 @@ $(function() {
self.editorVolumeFormFactor(data.volume.formFactor);

self.editorHeatedBed(data.heatedBed);
self.editorCenteredOrigin(data.centeredOrigin);

self.editorNozzleDiameter(data.extruder.nozzleDiameter);
self.editorExtruders(data.extruder.count);
Expand Down Expand Up @@ -349,6 +351,7 @@ $(function() {
formFactor: self.editorVolumeFormFactor()
},
heatedBed: self.editorHeatedBed(),
centeredOrigin: self.editorCenteredOrigin(),
extruder: {
count: parseInt(self.editorExtruders()),
offsets: [
Expand Down
Expand Up @@ -100,6 +100,14 @@
</div>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Bed Origin') }}</label>
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: printerProfiles.editorCenteredOrigin">{{ _('Origin (0, 0) is in the center of the bed') }}
</label>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Heated Bed') }}</label>
<div class="controls">
Expand Down

1 comment on commit fbe50e3

@foosel
Copy link

@foosel foosel commented on fbe50e3 Apr 15, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That takes care of the settings and the gcode viewer, but it completely forgoes the slicer which needs that information as well.

Take a look here, here and here.

.oO( Maybe I should extract that "where to position the model" stuff somehow so it doesn't need to be reimplemented in every slicer )

Please sign in to comment.