Skip to content

Commit 56d110c

Browse files
Fix: Fix 4.15.0 materials test bug (#2574)
Fix several laser meterial tests bug
1 parent 05ae29e commit 56d110c

30 files changed

+1352
-316
lines changed

.github/workflows/build-on-create-release.yml

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,28 @@ jobs:
136136
- name: Checkout submodules
137137
run: git submodule update --init --recursive
138138

139+
- name: Install system dependencies
140+
run: |
141+
sudo apt-get update
142+
sudo apt-get install -y python3 make g++ build-essential fontconfig libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
143+
144+
- name: Set up Python
145+
uses: actions/setup-python@v2
146+
with:
147+
python-version: 3.11
148+
149+
- name: Install dependencies
150+
run: |
151+
sudo ln -sf /usr/bin/python3 /usr/bin/python
152+
python -m pip install --upgrade pip
153+
139154
- name: Use Node.js 16
140155
uses: actions/setup-node@v3
141156
with:
142157
node-version: 16
143158

144-
- run: npm install -g npm@^9
145-
- run: npm install
159+
- run: npm install -g npm@^9 --unsafe-perm
160+
- run: npm install --unsafe-perm
146161

147162
- run: npm run build
148163

.github/workflows/build-on-pull-request.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -221,22 +221,28 @@ jobs:
221221
- name: Checkout submodules
222222
run: git submodule update --init --recursive
223223

224+
- name: Install system dependencies
225+
run: |
226+
sudo apt-get update
227+
sudo apt-get install -y python3 make g++ build-essential fontconfig libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
228+
224229
- name: Set up Python
225-
uses: actions/setup-python@v3
230+
uses: actions/setup-python@v2
226231
with:
227-
python-version: 3.11
232+
python-version: 3.11
228233

229234
- name: Install dependencies
230235
run: |
231-
python -m pip install --upgrade pip
236+
sudo ln -sf /usr/bin/python3 /usr/bin/python
237+
python -m pip install --upgrade pip
232238
233239
- name: Use Node.js 16
234240
uses: actions/setup-node@v3
235241
with:
236242
node-version: 16
237243

238-
- run: npm install -g npm@^9
239-
- run: npm install
244+
- run: npm install -g npm@^9 --unsafe-perm
245+
- run: npm install --unsafe-perm
240246

241247
- run: npm run build
242248

package-lock.json

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "snapmaker-luban",
3-
"version": "4.15.0-alpha.2",
3+
"version": "4.15.0",
44
"description": "A web-based interface for Snapmaker 3-in-1 3D Printer",
55
"homepage": "https://github.com/Snapmaker/Luban",
66
"author": "Snapmaker Software Team",

packages/luban-print-settings

src/app/flux/editor/index.ts

Lines changed: 153 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ import { actions as projectActions } from '../project';
7474
import { SVGClippingResultType, SVGClippingType } from '../../constants/clipping';
7575
import { actions as appGlobalActions } from '../app-global';
7676
import UpdateHrefOperation2D from '../operation-history/UpdateHrefOperation2D';
77+
import { toast } from '../../ui/components/Toast';
78+
import { makeSceneToast } from '../../ui/views/toasts/SceneToast';
79+
import AddMaterialTestGenerate from '../operation-history/AddMaterialTestGenerate';
7780

7881

7982
declare type HeadType = 'laser' | 'cnc';
@@ -1657,109 +1660,182 @@ export const actions = {
16571660
dispatch(actions.resetProcessState(headType));
16581661
},
16591662

1660-
createElementAndGenToolPath: (headType, params) => async (dispatch, getState) => {
1661-
const { modelGroup, SVGActions, toolPathGroup, coordinateMode, coordinateSize, materials } = getState()[headType];
1663+
createElementAndGenToolPath: (headType, params, gcodeConfig, toolParams) => async (dispatch, getState) => {
1664+
dispatch(actions.resetProcessState(headType));
1665+
const { progressStatesManager, modelGroup, SVGActions, toolPathGroup, coordinateMode, coordinateSize, materials } = getState()[headType];
16621666
const { rectRows, speedMin, speedMax, rectHeight, rectCols, powerMin, powerMax, rectWidth } = params;
16631667
const origin: Origin = getState()[headType].origin;
16641668

1665-
const gap = 5;
1666-
const headGap = 10;
1667-
const maxWidth = (rectCols * (gap + rectWidth)) + rectHeight + (gap + rectHeight);
1668-
const maxHeight = (rectRows + 3) * rectHeight + rectRows * gap + headGap;
1669-
const position = {
1670-
// TODO 画图在中心位计算坐标 坐标为可能有偏差,具体待验证
1671-
x: coordinateMode.setting.sizeMultiplyFactor.x * coordinateSize.x / 2 + (coordinateSize.x * 2 - maxWidth) / 2 + rectWidth,
1672-
y: -coordinateMode.setting.sizeMultiplyFactor.y * coordinateSize.y / 2 + ((maxHeight - headGap) / 2 - rectHeight * 1.5 + coordinateSize.y)
1669+
if (!progressStatesManager.inProgress()) {
1670+
progressStatesManager.startProgress(PROCESS_STAGE.CNC_LASER_PROCESS_IMAGE, [1]);
1671+
} else {
1672+
progressStatesManager.startNextStep();
1673+
}
1674+
1675+
const progress = (p) => {
1676+
if (p === 1) {
1677+
progressStatesManager.finishProgress(true);
1678+
}
1679+
if (p === -1) {
1680+
progressStatesManager.finishProgress(false);
1681+
p = 1;
1682+
}
1683+
dispatch(
1684+
actions.updateState(headType, {
1685+
stage: STEP_STAGE.CNC_LASER_PROCESSING_IMAGE,
1686+
progress: progressStatesManager.updateProgress(STEP_STAGE.CNC_LASER_PROCESSING_IMAGE, p)
1687+
})
1688+
);
16731689
};
1674-
// 越界判断,判断pass跟speed 最大高度
1675-
// 当前只支持工作原点为中心
1676-
if (maxWidth > coordinateSize.x || maxHeight > coordinateSize.y) {
1677-
log.error(`越界,xWidth:${maxWidth},y:${maxHeight}`);
1690+
1691+
const rectGap = 6;
1692+
const titleGap = 2;
1693+
// headTitleGap just use between head title and rects
1694+
const headTitleGap = 4;
1695+
const baseStyle = {
1696+
titleHeight: 2.5,
1697+
titleFontSize: 5,
1698+
numHeight: 2,
1699+
numFontSize: 4,
1700+
maxWidth: 16
1701+
};
1702+
if ((rectHeight < rectWidth ? rectHeight : rectWidth) > 4) {
1703+
baseStyle.titleHeight = 3;
1704+
baseStyle.titleFontSize = 8.5;
1705+
baseStyle.numHeight = 2;
1706+
baseStyle.numFontSize = 5.8;
1707+
baseStyle.maxWidth = 17.9;
1708+
}
1709+
if ((rectHeight < rectWidth ? rectHeight : rectWidth) > 6) {
1710+
baseStyle.titleHeight = 4;
1711+
baseStyle.titleFontSize = 11.2;
1712+
baseStyle.numHeight = 3;
1713+
baseStyle.numFontSize = 8.6;
1714+
baseStyle.maxWidth = 23.6;
1715+
}
1716+
const maxWidth = rectCols * (rectWidth + rectGap) - rectGap + titleGap * 2 + baseStyle.numHeight + baseStyle.titleHeight + (rectWidth > 3 ? 0 : 1);
1717+
const maxHeight = rectRows * (rectHeight + rectGap) - rectGap + headTitleGap + (titleGap + baseStyle.titleHeight) * 2 + baseStyle.numHeight;
1718+
progress(0.05);
1719+
// 越界判断
1720+
if (maxWidth > Math.max(coordinateSize.x, baseStyle.maxWidth) || maxHeight > coordinateSize.y) {
1721+
progress(-1);
1722+
toast(makeSceneToast('warning', `Need more workspace,limit width:${Math.max(coordinateSize.x, baseStyle.maxWidth, maxWidth)},limit height:${maxHeight}`));
16781723
return;
16791724
}
16801725

1726+
const position = {
1727+
x: SVGActions.size.x + coordinateMode.setting.sizeMultiplyFactor.x * coordinateSize.x / 2 - maxWidth / 2,
1728+
y: SVGActions.size.y - coordinateMode.setting.sizeMultiplyFactor.y * coordinateSize.y / 2 + maxHeight / 2
1729+
};
1730+
16811731
const toolPathBase = {
16821732
speed: (speedMax - speedMin) / ((rectRows - 1) || 1),
16831733
power: (powerMax - powerMin) / ((rectCols - 1) || 1),
16841734
};
16851735

1686-
const wordSpeed = (speedMax - speedMin) / 2 + speedMin;
1687-
const wordPower = (powerMax - powerMin) / 2 + powerMin;
1688-
const createElement = async (text, x, y, w, h, workspeed, fixedPower, needRote) => {
1689-
const curX = position.x + x;
1690-
const curY = position.y + y;
1691-
let svg;
1692-
if (text) {
1693-
svg = await SVGActions.svgContentGroup.addSVGElement({
1694-
element: 'text',
1695-
attr: {
1696-
x: curX,
1697-
y: curY,
1698-
'font-size': 24,
1699-
'font-family': 'Arial Black',
1700-
style: 'Regular',
1701-
alignment: 'left',
1702-
textContent: text,
1703-
width: w,
1704-
height: h,
1705-
}
1706-
});
1707-
} else {
1708-
svg = await SVGActions.svgContentGroup.addSVGElement({
1709-
element: 'rect',
1710-
attr: {
1711-
x: curX,
1712-
y: curY,
1713-
fill: '#ffffff',
1714-
'fill-opacity': '0',
1715-
opacity: '1',
1716-
stroke: '#000000',
1717-
'stroke-width': '0.2756410256410256',
1718-
width: w,
1719-
height: h,
1720-
}
1721-
});
1722-
}
1723-
const newSVGModel = await SVGActions.createModelFromElement(svg);
1724-
const textElement = document.getElementById(svg.id);
1725-
await SVGActions.resizeElementsImmediately([textElement], { newWidth: w, newHeight: h });
1726-
if (needRote) {
1727-
await SVGActions.rotateElementsImmediately([textElement], { newAngle: -90 });
1728-
}
1729-
modelGroup.selectedModelArray.push(newSVGModel);
1736+
const wordSpeed = Math.round((speedMax - speedMin) / 3 + speedMin);
1737+
const wordPower = Math.round((powerMax - powerMin) / 2 + powerMin);
1738+
const mergeList = [];
1739+
const backupModels = [];
1740+
const backupToolPath = [];
1741+
const createToolPath = (models, ws, fp) => {
1742+
modelGroup.selectedModelArray = models;
17301743
const toolPath = toolPathGroup.createToolPath({ materials, origin });
1731-
toolPath.gcodeConfig.workSpeed = workspeed;
1732-
toolPath.gcodeConfig.fixedPower = fixedPower;
1733-
toolPath.gcodeConfig.constantPowerMode = true;
1734-
toolPath.gcodeConfig.auxiliaryAirPump = true;
1735-
toolPath.gcodeConfig.halfDiodeMode = false;
1744+
toolPath.name = models.length > 1 ? `${models[0].modelName}-${models[models.length - 1].modelName}` : models[0].modelName;
1745+
toolPath.gcodeConfig = gcodeConfig;
1746+
toolPath.toolParams = toolParams;
1747+
toolPath.gcodeConfig.workSpeed = ws;
1748+
toolPath.gcodeConfig.fixedPower = fp;
17361749
if (toolPathGroup.getToolPath(toolPath.id)) {
17371750
toolPathGroup.updateToolPath(toolPath.id, toolPath, { materials, origin });
17381751
} else {
17391752
toolPathGroup.saveToolPath(toolPath, { materials, origin }, false);
17401753
}
1754+
backupToolPath.push(toolPath);
17411755
modelGroup.selectedModelArray = [];
17421756
};
1743-
await createElement('Passes', rectCols / 2 * (gap + rectWidth), -rectRows * (gap + rectHeight) - headGap, 20, rectHeight, wordSpeed, wordPower, false);
1744-
await createElement('Power(%)', rectCols / 2 * (gap + rectWidth) + rectHeight, 2 * rectHeight, 25, rectHeight, wordSpeed, wordPower, false);
1745-
await createElement('Speed(mm/m)', -rectWidth - rectHeight / 2, -rectRows / 2 * (gap + rectHeight), 30, rectHeight, wordSpeed, wordPower, true);
1746-
let x = 0;
1747-
let y = 0;
1757+
const createTextElement = async (text, x, y, h, fontSize, needRote) => {
1758+
const curX = position.x + x;
1759+
const curY = position.y + y;
1760+
const svg = await SVGActions.svgContentGroup.addSVGElement({
1761+
element: 'text',
1762+
attr: {
1763+
x: curX,
1764+
y: curY,
1765+
'font-size': fontSize,
1766+
'font-family': 'Helvetica LT Pro',
1767+
style: 'Regular',
1768+
alignment: 'left',
1769+
textContent: text,
1770+
height: h,
1771+
}
1772+
});
1773+
const newSVGModel = await SVGActions.createModelFromElement(svg);
1774+
const textElement = document.getElementById(svg.id);
1775+
if (needRote) {
1776+
await SVGActions.rotateElementsImmediately([textElement], { newAngle: -90 });
1777+
}
1778+
backupModels.push(newSVGModel);
1779+
mergeList.push(newSVGModel);
1780+
};
1781+
const createRectElement = async (x, y, w, h, ws, fp) => {
1782+
const curX = position.x + x;
1783+
const curY = position.y + y;
1784+
const svg = await SVGActions.svgContentGroup.addSVGElement({
1785+
element: 'rect',
1786+
attr: {
1787+
x: curX,
1788+
y: curY,
1789+
fill: '#ffffff',
1790+
'fill-opacity': '0',
1791+
opacity: '1',
1792+
stroke: '#000000',
1793+
'stroke-width': '0.2756410256410256',
1794+
width: w,
1795+
height: h,
1796+
}
1797+
});
1798+
const newSVGModel = await SVGActions.createModelFromElement(svg);
1799+
const textElement = document.getElementById(svg.id);
1800+
await SVGActions.resizeElementsImmediately([textElement], { newWidth: w, newHeight: h });
1801+
backupModels.push(newSVGModel);
1802+
createToolPath([newSVGModel], ws, fp);
1803+
};
1804+
1805+
await createTextElement(`Passes : ${gcodeConfig.multiPasses}`, maxWidth / 2, -maxHeight + baseStyle.titleHeight / 2, baseStyle.titleHeight, baseStyle.titleFontSize, false);
1806+
await createTextElement('Power(%)', maxWidth / 2, -baseStyle.titleHeight / 2, baseStyle.titleHeight, baseStyle.titleFontSize, false);
1807+
await createTextElement('Speed(mm/m)', baseStyle.titleHeight / 2, -maxHeight / 2, baseStyle.titleHeight, baseStyle.titleFontSize, true);
1808+
progress(0.1);
1809+
const basicX = baseStyle.titleHeight + baseStyle.numHeight + titleGap * 2;
1810+
const basicY = -(baseStyle.titleHeight + baseStyle.numHeight + titleGap * 2);
17481811
for (let i = 0; i < rectCols; i++) {
1749-
x += gap + rectWidth;
1750-
await createElement(`${Math.round(powerMin + i * toolPathBase.power)}`, x + rectWidth / 2, rectHeight / 2, rectHeight, rectWidth, wordSpeed, wordPower, false);
1751-
y = 0;
1812+
const x = basicX + i * (rectWidth + rectGap);
1813+
const curPower = Math.round(powerMin + i * toolPathBase.power);
17521814
for (let j = 0; j < rectRows; j++) {
1753-
y -= gap + rectHeight;
1815+
const y = basicY - j * (rectGap + rectHeight);
1816+
const curSpeed = Math.round(speedMin + j * toolPathBase.speed);
17541817
if (i === 0) {
1755-
await createElement(`${Math.round(speedMin + j * toolPathBase.speed)}`, x - rectWidth, y + rectHeight / 2, rectWidth, rectHeight, wordSpeed, wordPower, true);
1818+
await createTextElement(`${curSpeed}`, x - (titleGap + baseStyle.numHeight / 2), y - rectHeight / 2, baseStyle.numHeight, baseStyle.numFontSize, true);
1819+
}
1820+
if (j === 0) {
1821+
await createTextElement(`${curPower}`, x + rectWidth / 2, y + titleGap + baseStyle.numHeight / 2, baseStyle.numHeight, baseStyle.numFontSize, false);
17561822
}
1757-
await createElement(null, x, y, rectWidth, rectHeight, speedMin + j * toolPathBase.speed,
1758-
powerMin + i * toolPathBase.power, false);
1823+
await createRectElement(x, y - rectHeight, rectWidth, rectHeight, curSpeed, curPower);
17591824
}
1825+
progress(0.1 + (i + 1) * (0.9 / rectCols));
17601826
}
1761-
1762-
dispatch(projectActions.autoSaveEnvironment(headType));
1827+
createToolPath(mergeList, wordSpeed, wordPower);
1828+
progress(0.95);
1829+
const operation = new AddMaterialTestGenerate({
1830+
toolPathGroup: toolPathGroup,
1831+
modelGroup: modelGroup,
1832+
svgActions: SVGActions,
1833+
models: backupModels
1834+
});
1835+
const operations = new CompoundOperation();
1836+
operations.push(operation);
1837+
dispatch(operationHistoryActions.setOperations(headType, operations));
1838+
progress(1);
17631839
dispatch(baseActions.render(headType));
17641840
},
17651841

0 commit comments

Comments
 (0)