mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 17:56:03 +08:00
Distance of support point are modified by svg file.
- Support points are stored in separate list(no need to collect from grid + no duplicit support points) - Grid contain only indices into result vector of support points - Each layer is made update of radiuses for existing support points - Each support point knows support radius for current processed layer - Layers knows z coordinate soo heights in preparation are copied into layer.
This commit is contained in:
parent
3906b7dafc
commit
40d52994db
361
resources/data/sla_support.svg
Normal file
361
resources/data/sla_support.svg
Normal file
@ -0,0 +1,361 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="50mm"
|
||||||
|
height="50mm"
|
||||||
|
viewBox="0 0 50 50"
|
||||||
|
version="1.1"
|
||||||
|
id="svg3403"
|
||||||
|
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
|
||||||
|
sodipodi:docname="sla_support.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview3405"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="true"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="false"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
showborder="true"
|
||||||
|
borderlayer="true"
|
||||||
|
inkscape:zoom="3.3638608"
|
||||||
|
inkscape:cx="92.601929"
|
||||||
|
inkscape:cy="110.88449"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1129"
|
||||||
|
inkscape:window-x="1912"
|
||||||
|
inkscape:window-y="-8"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1" />
|
||||||
|
<defs
|
||||||
|
id="defs3400">
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="Arrow2"
|
||||||
|
refX="0"
|
||||||
|
refY="0"
|
||||||
|
orient="auto-start-reverse"
|
||||||
|
inkscape:stockid="Arrow2"
|
||||||
|
markerWidth="7.6999998"
|
||||||
|
markerHeight="5.5999999"
|
||||||
|
viewBox="0 0 7.7 5.6"
|
||||||
|
inkscape:isstock="true"
|
||||||
|
inkscape:collect="always"
|
||||||
|
preserveAspectRatio="xMidYMid">
|
||||||
|
<path
|
||||||
|
transform="scale(0.7)"
|
||||||
|
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
|
||||||
|
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||||
|
id="arrow2L" />
|
||||||
|
</marker>
|
||||||
|
<marker
|
||||||
|
style="overflow:visible"
|
||||||
|
id="Arrow2-5"
|
||||||
|
refX="0"
|
||||||
|
refY="0"
|
||||||
|
orient="auto-start-reverse"
|
||||||
|
inkscape:stockid="Arrow2"
|
||||||
|
markerWidth="7.6999998"
|
||||||
|
markerHeight="5.5999999"
|
||||||
|
viewBox="0 0 7.7 5.6"
|
||||||
|
inkscape:isstock="true"
|
||||||
|
inkscape:collect="always"
|
||||||
|
preserveAspectRatio="xMidYMid">
|
||||||
|
<path
|
||||||
|
transform="scale(0.7)"
|
||||||
|
d="M -2,-4 9,0 -2,4 c 2,-2.33 2,-5.66 0,-8 z"
|
||||||
|
style="fill:context-stroke;fill-rule:evenodd;stroke:none"
|
||||||
|
id="arrow2L-4" />
|
||||||
|
</marker>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:2.5;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,11.25 H 46.858514 50"
|
||||||
|
id="path13101"
|
||||||
|
sodipodi:nodetypes="ccc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="46.68829"
|
||||||
|
y="11.313486"
|
||||||
|
id="text13105"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan13103"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="46.68829"
|
||||||
|
y="11.313486">201. - 250. layer</tspan></text>
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:2.5;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,6.25 H 50"
|
||||||
|
id="path13095" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,1.3745207 H 50"
|
||||||
|
id="path13003" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,1.875 H 50"
|
||||||
|
id="path13005" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,2.375 H 50"
|
||||||
|
id="path13007" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,0.87396551 H 50"
|
||||||
|
id="path12741" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,0.375 H 50"
|
||||||
|
id="path12739" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.05;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,0.075 H 50"
|
||||||
|
id="path9670-6" />
|
||||||
|
<path
|
||||||
|
style="fill:#cccccc;stroke:#cccccc;stroke-width:0.05;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 0,0.175 H 50"
|
||||||
|
id="path12735" />
|
||||||
|
<path
|
||||||
|
style="fill:none;stroke:#b50000;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="M 5,0 6,3.8987591 8,15 10,40"
|
||||||
|
id="path3587"
|
||||||
|
sodipodi:nodetypes="cccc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:1.05833px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:center;text-decoration-color:#000000;text-anchor:middle;fill:#364e59;stroke:none;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="16.386877"
|
||||||
|
y="-7.5019774"
|
||||||
|
id="text4929"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4927"
|
||||||
|
style="font-size:1.05833px;fill:#364e59;stroke:none;stroke-width:0.4"
|
||||||
|
x="16.386877"
|
||||||
|
y="-7.5019774">island supports</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:2.11667px;line-height:1.3;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:center;text-decoration-color:#000000;text-anchor:middle;fill:#364e59;stroke:none;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="24.711193"
|
||||||
|
y="52.296951"
|
||||||
|
id="text4985"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan4983"
|
||||||
|
style="font-weight:normal;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="24.711193"
|
||||||
|
y="52.296951">For loading is used only first red curve</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:normal;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="24.711193"
|
||||||
|
y="55.048622"
|
||||||
|
id="tspan9281">Use only line segments (no curve)</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:normal;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="24.711193"
|
||||||
|
y="57.800293"
|
||||||
|
id="tspan15589">Y coordinate of points must only increase.</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:normal;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="24.711193"
|
||||||
|
y="60.551964"
|
||||||
|
id="tspan17460">First point.y must be zero</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:normal;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="24.711193"
|
||||||
|
y="63.303635"
|
||||||
|
id="tspan9676" /></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:2.11667px;line-height:1.3;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:center;text-decoration-color:#000000;text-anchor:middle;fill:#364e59;stroke:none;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="33.019527"
|
||||||
|
y="-2.8043785"
|
||||||
|
id="text4985-7"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:bold;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="33.019527"
|
||||||
|
y="-2.8043785"
|
||||||
|
id="tspan9281-8">Supported radius[in mm]</tspan></text>
|
||||||
|
<rect
|
||||||
|
style="fill:#ba00ff;stroke:none;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
id="rect6552"
|
||||||
|
width="0.39999992"
|
||||||
|
height="1"
|
||||||
|
x="-0.2"
|
||||||
|
y="0" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:1.05833px;line-height:1.2;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:center;text-decoration-color:#000000;text-anchor:middle;fill:#ba00ff;stroke:none;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="-0.38932067"
|
||||||
|
y="-1.6407087"
|
||||||
|
id="text6608"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:1.05833px;text-align:center;text-anchor:middle;stroke-width:0.4"
|
||||||
|
x="-0.38932067"
|
||||||
|
y="-1.6407087"
|
||||||
|
id="tspan7386">Head</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-size:1.05833px;text-align:center;text-anchor:middle;stroke-width:0.4"
|
||||||
|
x="-0.38932067"
|
||||||
|
y="-0.3707087"
|
||||||
|
id="tspan7390">interface</tspan></text>
|
||||||
|
<path
|
||||||
|
style="fill:#ba00ff;stroke:#364e59;stroke-width:0.1;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#Arrow2);stop-color:#000000"
|
||||||
|
d="M 13.379759,-7.2418186 10.65352,-0.96342022"
|
||||||
|
id="path7457"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:1.67576px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:center;text-decoration-color:#000000;text-anchor:middle;fill:#364e59;stroke:none;stroke-width:0.1;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="15.351564"
|
||||||
|
y="55.742996"
|
||||||
|
id="text9279"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan9277"
|
||||||
|
style="fill:#364e59;stroke:none;stroke-width:0.1"
|
||||||
|
x="15.351564"
|
||||||
|
y="55.742996" /></text>
|
||||||
|
<path
|
||||||
|
style="fill:#364e59;stroke:#364e59;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000;marker-end:url(#Arrow2)"
|
||||||
|
d="M 29.365905,-1.4460483 H 48.609472"
|
||||||
|
id="path9401" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:2.06203px;line-height:1.3;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:center;text-decoration-color:#000000;text-anchor:middle;fill:#364e59;stroke:none;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="-8.5609999"
|
||||||
|
y="41.920982"
|
||||||
|
id="text4985-7-3"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:bold;font-size:2.11667px;stroke-width:0.4"
|
||||||
|
x="-8.5609999"
|
||||||
|
y="41.920982"
|
||||||
|
id="tspan9281-8-8">z [in mm]</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:normal;font-size:1.05833px;stroke-width:0.4"
|
||||||
|
x="-8.5609999"
|
||||||
|
y="44.620838"
|
||||||
|
id="tspan9668"
|
||||||
|
dy="-1.0011104">Print Direction</tspan></text>
|
||||||
|
<path
|
||||||
|
style="fill:#364e59;stroke:#364e59;stroke-width:0.4;stroke-linejoin:round;stroke-dasharray:none;marker-end:url(#Arrow2-5);stop-color:#000000"
|
||||||
|
d="M -2.7788881,27.725679 V 46.969247"
|
||||||
|
id="path9401-5" />
|
||||||
|
<path
|
||||||
|
style="fill:#364e59;stroke:#364e59;stroke-width:0.1;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
d="m 10.778332,39.821948 48.064712,0"
|
||||||
|
id="path9670"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:1.05833px;line-height:1.3;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#364e59;stroke:#364e59;stroke-width:0.1;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="50.865135"
|
||||||
|
y="39.457973"
|
||||||
|
id="text9674"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan9672"
|
||||||
|
style="font-weight:normal;font-size:1.05833px;stroke:none;stroke-width:0.1;text-anchor:start;text-align:start"
|
||||||
|
x="59.791695"
|
||||||
|
y="39.457973">Last curve point</tspan><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="font-weight:normal;font-size:1.05833px;stroke:none;stroke-width:0.1;text-anchor:start;text-align:start"
|
||||||
|
x="59.791695"
|
||||||
|
y="40.833801"
|
||||||
|
id="tspan9678">define stability requirements</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="47.136429"
|
||||||
|
y="0.44968146"
|
||||||
|
id="text12797"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan12795"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="47.136429"
|
||||||
|
y="0.44968146">6. - 10. layer</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:1.05833px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="50.574947"
|
||||||
|
y="0.98318326"
|
||||||
|
id="text13011"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
style="stroke-width:0.25"
|
||||||
|
x="50.574947"
|
||||||
|
y="0.98318326"
|
||||||
|
id="tspan13013">Guid for layers height 0.05mm</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="46.987049"
|
||||||
|
y="0.9476288"
|
||||||
|
id="text13029"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan13027"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="46.987049"
|
||||||
|
y="0.9476288">16. - 20. layer</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="46.987049"
|
||||||
|
y="1.448184"
|
||||||
|
id="text13033"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan13031"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="46.987049"
|
||||||
|
y="1.448184">26. - 30. layer</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="46.987049"
|
||||||
|
y="1.941787"
|
||||||
|
id="text13037"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan13035"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="46.987049"
|
||||||
|
y="1.941787">36. - 40. layer</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="46.987049"
|
||||||
|
y="2.4423423"
|
||||||
|
id="text13041"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan13039"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="46.987049"
|
||||||
|
y="2.4423423">46. - 50. layer</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:0.25494px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:0.25;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="46.68829"
|
||||||
|
y="6.3134861"
|
||||||
|
id="text13099"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan13097"
|
||||||
|
style="fill:#ffffff;stroke:none;stroke-width:0.25"
|
||||||
|
x="46.68829"
|
||||||
|
y="6.3134861">101. - 150. layer</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:1.05833px;line-height:0;font-family:'Cascadia Code';-inkscape-font-specification:'Cascadia Code';text-align:start;text-decoration-color:#000000;text-anchor:start;fill:#ffffff;stroke:none;stroke-width:2.5;stroke-linejoin:round;stroke-dasharray:none;stop-color:#000000"
|
||||||
|
x="14.708422"
|
||||||
|
y="-6.6856461"
|
||||||
|
id="text17458"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan17456"
|
||||||
|
style="stroke-width:2.5"></tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 16 KiB |
@ -22,21 +22,24 @@ class Grid2D
|
|||||||
coord_t m_cell_size; // Squar: x and y are same
|
coord_t m_cell_size; // Squar: x and y are same
|
||||||
coord_t m_cell_size_half;
|
coord_t m_cell_size_half;
|
||||||
|
|
||||||
using Key = Point;
|
using Key = Point; // scaled point
|
||||||
|
using Value = size_t; // index into m_supports_ptr
|
||||||
struct GridHash{std::size_t operator()(const Key &cell_id) const {
|
struct GridHash{std::size_t operator()(const Key &cell_id) const {
|
||||||
return std::hash<int>()(cell_id.x()) ^ std::hash<int>()(cell_id.y() * 593);
|
return std::hash<int>()(cell_id.x()) ^ std::hash<int>()(cell_id.y() * 593);
|
||||||
}};
|
}};
|
||||||
using Grid = std::unordered_multimap<Key, LayerSupportPoint, GridHash>;
|
using Grid = std::unordered_multimap<Key, Value, GridHash>;
|
||||||
Grid m_grid;
|
Grid m_grid;
|
||||||
|
// multiple grids points into same data storage of support points
|
||||||
|
LayerSupportPoints *m_supports_ptr;
|
||||||
public:
|
public:
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Set cell size for grid
|
/// Set cell size for grid
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cell_size">Granularity of stored points
|
/// <param name="cell_size">Granularity of stored points
|
||||||
/// Must be bigger than maximal used radius</param>
|
/// Must be bigger than maximal used radius</param>
|
||||||
explicit Grid2D(const coord_t &cell_size)
|
/// <param name="supports_ptr">Pointer on Support vector</param>
|
||||||
: m_cell_size(cell_size), m_cell_size_half(cell_size / 2) {}
|
explicit Grid2D(const coord_t &cell_size, LayerSupportPoints* supports_ptr)
|
||||||
|
: m_cell_size(cell_size), m_cell_size_half(cell_size / 2), m_supports_ptr(supports_ptr) {}
|
||||||
|
|
||||||
Key cell_id(const Point &point) const {
|
Key cell_id(const Point &point) const {
|
||||||
Key::coord_type x = point.x() / m_cell_size;
|
Key::coord_type x = point.x() / m_cell_size;
|
||||||
@ -48,11 +51,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void add(LayerSupportPoint &&point) {
|
void add(LayerSupportPoint &&point) {
|
||||||
m_grid.emplace(cell_id(point.position_on_layer), std::move(point));
|
size_t index = m_supports_ptr->size();
|
||||||
|
m_supports_ptr->emplace_back(std::move(point));
|
||||||
|
m_grid.emplace(cell_id(point.position_on_layer), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
using CheckFnc = std::function<bool(const LayerSupportPoint &, const Point&)>;
|
using CheckFnc = std::function<bool(const LayerSupportPoint &, const Point&)>;
|
||||||
bool exist_true_in_4cell_neighbor(const Point &pos, const CheckFnc& fnc) const {
|
bool exist_true_in_4cell_neighbor(const Point &pos, const CheckFnc& fnc) const {
|
||||||
|
// TODO: remove - test all support points without grid speed up
|
||||||
|
for (const auto &[key, value]: m_grid)
|
||||||
|
if(fnc(m_supports_ptr->at(value), pos))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
|
||||||
Key key = cell_id(pos);
|
Key key = cell_id(pos);
|
||||||
if (exist_true_for_cell(key, pos, fnc)) return true;
|
if (exist_true_for_cell(key, pos, fnc)) return true;
|
||||||
Point un_cell_pos(
|
Point un_cell_pos(
|
||||||
@ -72,19 +83,11 @@ public:
|
|||||||
assert(m_cell_size == grid.m_cell_size);
|
assert(m_cell_size == grid.m_cell_size);
|
||||||
m_grid.merge(std::move(grid.m_grid));
|
m_grid.merge(std::move(grid.m_grid));
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerSupportPoints get_points() const {
|
|
||||||
LayerSupportPoints result;
|
|
||||||
result.reserve(m_grid.size());
|
|
||||||
for (const auto& [key, support] : m_grid)
|
|
||||||
result.push_back(support);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
bool exist_true_for_cell(const Key &key, const Point &pos, const CheckFnc& fnc) const{
|
bool exist_true_for_cell(const Key &key, const Point &pos, const CheckFnc& fnc) const{
|
||||||
auto [begin_it, end_it] = m_grid.equal_range(key);
|
auto [begin_it, end_it] = m_grid.equal_range(key);
|
||||||
for (Grid::const_iterator it = begin_it; it != end_it; ++it) {
|
for (Grid::const_iterator it = begin_it; it != end_it; ++it) {
|
||||||
const LayerSupportPoint &support_point = it->second;
|
const LayerSupportPoint &support_point = m_supports_ptr->at(it->second);
|
||||||
if (fnc(support_point, pos))
|
if (fnc(support_point, pos))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -135,34 +138,25 @@ Point intersection(const Point &p1, const Point &p2, const Point &cnt, double r2
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
coord_t get_supported_radius(const LayerSupportPoint &p, float z_distance, const SupportPointGeneratorConfig &config
|
/// <summary>
|
||||||
) {
|
/// Move grid from previous layer to current one
|
||||||
// TODO: calculate support radius
|
/// for given part
|
||||||
return scale_(5.);
|
/// </summary>
|
||||||
}
|
/// <param name="prev_layer_parts">Grids generated in previous layer</param>
|
||||||
|
/// <param name="part">Current layer part to process</param>
|
||||||
void sample_part(
|
/// <param name="prev_grids">Grids which will be moved to current grid</param>
|
||||||
|
/// <returns>Grid for given part</returns>
|
||||||
|
Grid2D create_part_grid(
|
||||||
|
const LayerParts &prev_layer_parts,
|
||||||
const LayerPart &part,
|
const LayerPart &part,
|
||||||
size_t layer_id,
|
|
||||||
const SupportPointGeneratorData &data,
|
|
||||||
const SupportPointGeneratorConfig &config,
|
|
||||||
std::vector<Grid2D> &grids,
|
|
||||||
std::vector<Grid2D> &prev_grids
|
std::vector<Grid2D> &prev_grids
|
||||||
) {
|
) {
|
||||||
// NOTE: first layer do not have prev part
|
|
||||||
assert(layer_id != 0);
|
|
||||||
|
|
||||||
const Layers &layers = data.layers;
|
|
||||||
const LayerParts &prev_layer_parts = layers[layer_id - 1].parts;
|
|
||||||
const LayerParts::const_iterator &prev_part_it = part.prev_parts.front().part_it;
|
const LayerParts::const_iterator &prev_part_it = part.prev_parts.front().part_it;
|
||||||
size_t index_of_prev_part = prev_part_it - prev_layer_parts.begin();
|
size_t index_of_prev_part = prev_part_it - prev_layer_parts.begin();
|
||||||
if (prev_part_it->next_parts.size() == 1) {
|
Grid2D part_grid = (prev_part_it->next_parts.size() == 1)?
|
||||||
grids.push_back(std::move(prev_grids[index_of_prev_part]));
|
std::move(prev_grids[index_of_prev_part]) :
|
||||||
} else { // Need a copy there are multiple parts above previus one
|
// Need a copy there are multiple parts above previus one
|
||||||
grids.push_back(prev_grids[index_of_prev_part]); // copy
|
prev_grids[index_of_prev_part]; // copy
|
||||||
}
|
|
||||||
// current part grid
|
|
||||||
Grid2D &part_grid = grids.back();
|
|
||||||
|
|
||||||
// merge other grid in case of multiple previous parts
|
// merge other grid in case of multiple previous parts
|
||||||
for (size_t i = 1; i < part.prev_parts.size(); ++i) {
|
for (size_t i = 1; i < part.prev_parts.size(); ++i) {
|
||||||
@ -175,16 +169,32 @@ void sample_part(
|
|||||||
part_grid.merge(std::move(grid_));
|
part_grid.merge(std::move(grid_));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return part_grid;
|
||||||
|
}
|
||||||
|
|
||||||
float part_z = data.heights[layer_id];
|
/// <summary>
|
||||||
Grid2D::CheckFnc is_supported = [part_z, &config]
|
/// Add support point to part_grid when it is neccessary
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="part">Current part - keep samples</param>
|
||||||
|
/// <param name="config">Configuration to sample</param>
|
||||||
|
/// <param name="part_grid">Keep previous sampled suppport points</param>
|
||||||
|
/// <param name="part_z">current z coordinate of part</param>
|
||||||
|
void support_part_overhangs(
|
||||||
|
const LayerPart &part,
|
||||||
|
const SupportPointGeneratorConfig &config,
|
||||||
|
Grid2D &part_grid,
|
||||||
|
float part_z
|
||||||
|
) {
|
||||||
|
Grid2D::CheckFnc is_supported = []
|
||||||
(const LayerSupportPoint &support_point, const Point &p) -> bool {
|
(const LayerSupportPoint &support_point, const Point &p) -> bool {
|
||||||
float diff_height = part_z - support_point.pos.z();
|
// Debug visualization of all sampled outline
|
||||||
coord_t r_ = get_supported_radius(support_point, diff_height, config);
|
//return false;
|
||||||
|
|
||||||
|
coord_t r = support_point.current_radius;
|
||||||
Point dp = support_point.position_on_layer - p;
|
Point dp = support_point.position_on_layer - p;
|
||||||
if (std::abs(dp.x()) > r_) return false;
|
if (std::abs(dp.x()) > r) return false;
|
||||||
if (std::abs(dp.y()) > r_) return false;
|
if (std::abs(dp.y()) > r) return false;
|
||||||
double r2 = static_cast<double>(r_);
|
double r2 = static_cast<double>(r);
|
||||||
r2 *= r2;
|
r2 *= r2;
|
||||||
return dp.cast<double>().squaredNorm() < r2;
|
return dp.cast<double>().squaredNorm() < r2;
|
||||||
};
|
};
|
||||||
@ -201,7 +211,9 @@ void sample_part(
|
|||||||
SupportPointType::slope
|
SupportPointType::slope
|
||||||
},
|
},
|
||||||
/* position_on_layer */ p,
|
/* position_on_layer */ p,
|
||||||
/* direction_to_mass */ Point(1,0)
|
/* direction_to_mass */ Point(1,0), // TODO: change direction
|
||||||
|
/* radius_curve_index */ 0,
|
||||||
|
/* current_radius */ static_cast<coord_t>(scale_(config.support_curve.front().x()))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,14 +224,16 @@ Points uniformly_sample(const ExPolygon &island, const SupportPointGeneratorConf
|
|||||||
return Points{island.contour.centroid()};
|
return Points{island.contour.centroid()};
|
||||||
}
|
}
|
||||||
|
|
||||||
Grid2D support_island(const LayerPart &part, float part_z, const SupportPointGeneratorConfig &cfg) {
|
/// <summary>
|
||||||
// Maximal radius of supported area of one support point
|
/// Sample part as Island
|
||||||
double max_support_radius = 10.; // cfg.cell_size;
|
/// Result store to grid
|
||||||
|
/// </summary>
|
||||||
// maximal radius of support
|
/// <param name="part">Island to support</param>
|
||||||
coord_t cell_size = scale_(max_support_radius);
|
/// <param name="part_grid">OUT place to store new supports</param>
|
||||||
|
/// <param name="part_z">z coordinate of part</param>
|
||||||
Grid2D part_grid(cell_size);
|
/// <param name="cfg"></param>
|
||||||
|
void support_island(const LayerPart &part, Grid2D& part_grid, float part_z,
|
||||||
|
const SupportPointGeneratorConfig &cfg) {
|
||||||
Points pts = uniformly_sample(*part.shape, cfg);
|
Points pts = uniformly_sample(*part.shape, cfg);
|
||||||
for (const Point &pt : pts)
|
for (const Point &pt : pts)
|
||||||
part_grid.add(LayerSupportPoint{
|
part_grid.add(LayerSupportPoint{
|
||||||
@ -229,9 +243,10 @@ Grid2D support_island(const LayerPart &part, float part_z, const SupportPointGen
|
|||||||
SupportPointType::island
|
SupportPointType::island
|
||||||
},
|
},
|
||||||
/* position_on_layer */ pt,
|
/* position_on_layer */ pt,
|
||||||
/* direction_to_mass */ Point(0,0) // direction from bottom
|
/* direction_to_mass */ Point(0,0), // direction from bottom
|
||||||
|
/* radius_curve_index */ 0,
|
||||||
|
/* current_radius */ static_cast<coord_t>(scale_(cfg.support_curve.front().x()))
|
||||||
});
|
});
|
||||||
return part_grid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -274,18 +289,19 @@ Slic3r::Points sample(Points::const_iterator b, Points::const_iterator e, double
|
|||||||
Slic3r::Points r;
|
Slic3r::Points r;
|
||||||
r.push_back(*b);
|
r.push_back(*b);
|
||||||
|
|
||||||
Points::const_iterator prev_pt = e;
|
//Points::const_iterator prev_pt = e;
|
||||||
|
const Point *prev_pt = nullptr;
|
||||||
for (Points::const_iterator it = b; it+1 < e; ++it){
|
for (Points::const_iterator it = b; it+1 < e; ++it){
|
||||||
const Point &pt = *(it+1);
|
const Point &pt = *(it+1);
|
||||||
double p_dist2 = (r.back() - pt).cast<double>().squaredNorm();
|
double p_dist2 = (r.back() - pt).cast<double>().squaredNorm();
|
||||||
while (p_dist2 > dist2) { // line segment goes out of radius
|
while (p_dist2 > dist2) { // line segment goes out of radius
|
||||||
if (prev_pt == e)
|
if (prev_pt == nullptr)
|
||||||
prev_pt = it;
|
prev_pt = &(*it);
|
||||||
r.push_back(intersection(*prev_pt, pt, r.back(), dist2));
|
r.push_back(intersection(*prev_pt, pt, r.back(), dist2));
|
||||||
p_dist2 = (r.back() - pt).cast<double>().squaredNorm();
|
p_dist2 = (r.back() - pt).cast<double>().squaredNorm();
|
||||||
prev_pt = r.end()-1; // r.back()
|
prev_pt = &r.back();
|
||||||
}
|
}
|
||||||
prev_pt = e;
|
prev_pt = nullptr;
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -382,13 +398,43 @@ Points sample_overhangs(const LayerPart& part, double dist2) {
|
|||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void prepare_supports_for_layer(LayerSupportPoints &supports, float layer_z,
|
||||||
|
const SupportPointGeneratorConfig &config) {
|
||||||
|
const std::vector<Vec2f>& curve = config.support_curve;
|
||||||
|
// calculate support area for each support point as radius
|
||||||
|
// IMPROVE: use some offsets of previous supported island
|
||||||
|
for (LayerSupportPoint &support : supports) {
|
||||||
|
size_t &index = support.radius_curve_index;
|
||||||
|
if (index + 1 >= curve.size())
|
||||||
|
continue; // already contain maximal radius
|
||||||
|
|
||||||
|
// find current segment
|
||||||
|
float diff_z = layer_z - support.pos.z();
|
||||||
|
while ((index + 1) < curve.size() && diff_z > curve[index + 1].y())
|
||||||
|
++index;
|
||||||
|
|
||||||
|
if ((index+1) >= curve.size()) {
|
||||||
|
// set maximal radius
|
||||||
|
support.current_radius = static_cast<coord_t>(scale_(curve.back().x()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// interpolate radius on input curve
|
||||||
|
Vec2f a = curve[index];
|
||||||
|
Vec2f b = curve[index+1];
|
||||||
|
assert(a.y() <= diff_z && diff_z <= b.y());
|
||||||
|
float t = (diff_z - a.y()) / (b.y() - a.y());
|
||||||
|
assert(0 <= t && t <= 1);
|
||||||
|
support.current_radius = static_cast<coord_t>(scale_(a.x() + t * (b.x() - a.x())));
|
||||||
|
}
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#include "libslic3r/Execution/ExecutionSeq.hpp"
|
#include "libslic3r/Execution/ExecutionSeq.hpp"
|
||||||
|
|
||||||
SupportPointGeneratorData Slic3r::sla::prepare_generator_data(
|
SupportPointGeneratorData Slic3r::sla::prepare_generator_data(
|
||||||
std::vector<ExPolygons> &&slices,
|
std::vector<ExPolygons> &&slices,
|
||||||
std::vector<float> &&heights,
|
const std::vector<float> &heights,
|
||||||
ThrowOnCancel throw_on_cancel,
|
ThrowOnCancel throw_on_cancel,
|
||||||
StatusFunction statusfn
|
StatusFunction statusfn
|
||||||
) {
|
) {
|
||||||
@ -401,20 +447,20 @@ SupportPointGeneratorData Slic3r::sla::prepare_generator_data(
|
|||||||
// Move input into result
|
// Move input into result
|
||||||
SupportPointGeneratorData result;
|
SupportPointGeneratorData result;
|
||||||
result.slices = std::move(slices);
|
result.slices = std::move(slices);
|
||||||
result.heights = std::move(heights);
|
|
||||||
|
|
||||||
// Allocate empty layers.
|
// Allocate empty layers.
|
||||||
result.layers = Layers(result.slices.size(), {});
|
result.layers = Layers(result.slices.size(), {});
|
||||||
|
|
||||||
// Generate Extents and SampleLayers
|
// Generate Extents and SampleLayers
|
||||||
execution::for_each(ex_tbb, size_t(0), result.slices.size(),
|
execution::for_each(ex_tbb, size_t(0), result.slices.size(),
|
||||||
[&result, throw_on_cancel](size_t layer_id) {
|
[&result, &heights, throw_on_cancel](size_t layer_id) {
|
||||||
if ((layer_id % 8) == 0)
|
if ((layer_id % 8) == 0)
|
||||||
// Don't call the following function too often as it flushes
|
// Don't call the following function too often as it flushes
|
||||||
// CPU write caches due to synchronization primitves.
|
// CPU write caches due to synchronization primitves.
|
||||||
throw_on_cancel();
|
throw_on_cancel();
|
||||||
|
|
||||||
Layer &layer = result.layers[layer_id];
|
Layer &layer = result.layers[layer_id];
|
||||||
|
layer.print_z = heights[layer_id]; // copy
|
||||||
const ExPolygons &islands = result.slices[layer_id];
|
const ExPolygons &islands = result.slices[layer_id];
|
||||||
layer.parts.reserve(islands.size());
|
layer.parts.reserve(islands.size());
|
||||||
for (const ExPolygon &island : islands) {
|
for (const ExPolygon &island : islands) {
|
||||||
@ -467,6 +513,42 @@ SupportPointGeneratorData Slic3r::sla::prepare_generator_data(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "libslic3r/NSVGUtils.hpp"
|
||||||
|
#include "libslic3r/Utils.hpp"
|
||||||
|
std::vector<Vec2f> load_curve_from_file() {
|
||||||
|
std::string filePath = Slic3r::resources_dir() + "/data/sla_support.svg";
|
||||||
|
EmbossShape::SvgFile svg_file{filePath};
|
||||||
|
NSVGimage *image = init_image(svg_file);
|
||||||
|
|
||||||
|
for (NSVGshape *shape_ptr = image->shapes; shape_ptr != NULL; shape_ptr = shape_ptr->next) {
|
||||||
|
const NSVGshape &shape = *shape_ptr;
|
||||||
|
if (!(shape.flags & NSVG_FLAGS_VISIBLE)) continue; // is visible
|
||||||
|
if (shape.fill.type != NSVG_PAINT_NONE) continue; // is not used fill
|
||||||
|
if (shape.stroke.type == NSVG_PAINT_NONE) continue; // exist stroke
|
||||||
|
if (shape.strokeWidth < 1e-5f) continue; // is visible stroke width
|
||||||
|
if (shape.stroke.color != 4278190261) continue; // is red
|
||||||
|
|
||||||
|
// use only first path
|
||||||
|
const NSVGpath *path = shape.paths;
|
||||||
|
size_t count_points = path->npts;
|
||||||
|
assert(count_points > 1);
|
||||||
|
--count_points;
|
||||||
|
std::vector<Vec2f> points;
|
||||||
|
points.reserve(count_points/3+1);
|
||||||
|
points.push_back({path->pts[0], path->pts[1]});
|
||||||
|
for (size_t i = 0; i < count_points; i += 3) {
|
||||||
|
const float *p = &path->pts[i * 2];
|
||||||
|
points.push_back({p[6], p[7]});
|
||||||
|
}
|
||||||
|
assert(points.size() >= 2);
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// red curve line is not found
|
||||||
|
assert(false);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
LayerSupportPoints Slic3r::sla::generate_support_points(
|
LayerSupportPoints Slic3r::sla::generate_support_points(
|
||||||
const SupportPointGeneratorData &data,
|
const SupportPointGeneratorData &data,
|
||||||
const SupportPointGeneratorConfig &config,
|
const SupportPointGeneratorConfig &config,
|
||||||
@ -478,30 +560,41 @@ LayerSupportPoints Slic3r::sla::generate_support_points(
|
|||||||
double status = 0; // current progress
|
double status = 0; // current progress
|
||||||
int status_int = 0;
|
int status_int = 0;
|
||||||
|
|
||||||
|
// Hack to set curve for testing
|
||||||
|
if (config.support_curve.empty())
|
||||||
|
const_cast<SupportPointGeneratorConfig &>(config).support_curve = load_curve_from_file();
|
||||||
|
|
||||||
|
// Maximal radius of supported area of one support point
|
||||||
|
double max_support_radius = config.support_curve.back().x(); // cfg.cell_size;
|
||||||
|
// maximal radius of support
|
||||||
|
coord_t cell_size = scale_(2*max_support_radius);
|
||||||
|
|
||||||
|
// Storage for support points used by grid
|
||||||
LayerSupportPoints result;
|
LayerSupportPoints result;
|
||||||
|
|
||||||
|
// grid index == part in layer index
|
||||||
std::vector<Grid2D> prev_grids; // same count as previous layer item size
|
std::vector<Grid2D> prev_grids; // same count as previous layer item size
|
||||||
for (size_t layer_id = 0; layer_id < layers.size(); ++layer_id) {
|
for (size_t layer_id = 0; layer_id < layers.size(); ++layer_id) {
|
||||||
const Layer &layer = layers[layer_id];
|
const Layer &layer = layers[layer_id];
|
||||||
|
|
||||||
|
prepare_supports_for_layer(result, layer.print_z, config);
|
||||||
|
|
||||||
|
// grid index == part in layer index
|
||||||
std::vector<Grid2D> grids;
|
std::vector<Grid2D> grids;
|
||||||
grids.reserve(layer.parts.size());
|
grids.reserve(layer.parts.size());
|
||||||
|
|
||||||
for (const LayerPart &part : layer.parts) {
|
for (const LayerPart &part : layer.parts) {
|
||||||
if (part.prev_parts.empty()) {
|
if (part.prev_parts.empty()) {
|
||||||
|
// only island add new grid
|
||||||
|
grids.emplace_back(cell_size, &result);
|
||||||
// new island - needs support no doubt
|
// new island - needs support no doubt
|
||||||
float part_z = data.heights[layer_id];
|
support_island(part, grids.back(), layer.print_z, config);
|
||||||
grids.push_back(support_island(part, part_z, config));
|
|
||||||
} else {
|
} else {
|
||||||
sample_part(part, layer_id, data, config, grids, prev_grids);
|
// first layer should have empty prev_part
|
||||||
}
|
assert(layer_id != 0);
|
||||||
|
const LayerParts &prev_layer_parts = layers[layer_id - 1].parts;
|
||||||
// collect result from grid of top part
|
grids.push_back(create_part_grid(prev_layer_parts, part, prev_grids));
|
||||||
if (part.next_parts.empty()) {
|
support_part_overhangs(part, config, grids.back(), layer.print_z);
|
||||||
const Grid2D &part_grid = grids.back();
|
|
||||||
LayerSupportPoints sps = part_grid.get_points();
|
|
||||||
result.insert(result.end(),
|
|
||||||
std::make_move_iterator(sps.begin()),
|
|
||||||
std::make_move_iterator(sps.end()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
prev_grids = std::move(grids);
|
prev_grids = std::move(grids);
|
||||||
|
@ -40,6 +40,12 @@ struct SupportPointGeneratorConfig{
|
|||||||
// Minimal island Area to print - TODO: Should be modifiable from UI
|
// Minimal island Area to print - TODO: Should be modifiable from UI
|
||||||
// !! Filter should be out of sampling algorithm !!
|
// !! Filter should be out of sampling algorithm !!
|
||||||
float minimal_island_area = pow(0.047f, 2.f); // [in mm^2] pixel_area
|
float minimal_island_area = pow(0.047f, 2.f); // [in mm^2] pixel_area
|
||||||
|
|
||||||
|
// maximal distance to nearest support point(define radiuses per layer)
|
||||||
|
// x axis .. mean distance on layer(XY)
|
||||||
|
// y axis .. mean difference of height(Z)
|
||||||
|
// Points of lines [in mm]
|
||||||
|
std::vector<Vec2f> support_curve;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LayerPart; // forward decl.
|
struct LayerPart; // forward decl.
|
||||||
@ -93,6 +99,15 @@ struct LayerSupportPoint: public SupportPoint
|
|||||||
// used as ray to positioning 3d point on mesh surface
|
// used as ray to positioning 3d point on mesh surface
|
||||||
// Island has direction [0,0] - should be placed on surface from bottom
|
// Island has direction [0,0] - should be placed on surface from bottom
|
||||||
Point direction_to_mass;
|
Point direction_to_mass;
|
||||||
|
|
||||||
|
// index into curve to faster found radius for current layer
|
||||||
|
size_t radius_curve_index = 0;
|
||||||
|
coord_t current_radius = 0; // [in scaled mm]
|
||||||
|
|
||||||
|
// information whether support point is active in current investigated layer
|
||||||
|
// Flagged false when no part on layer in Radius 'r' around support point
|
||||||
|
// Tool to support overlapped overhang area multiple times
|
||||||
|
bool active_in_part = true;
|
||||||
};
|
};
|
||||||
using LayerSupportPoints = std::vector<LayerSupportPoint>;
|
using LayerSupportPoints = std::vector<LayerSupportPoint>;
|
||||||
|
|
||||||
@ -106,8 +121,7 @@ struct Layer
|
|||||||
size_t layer_id;
|
size_t layer_id;
|
||||||
|
|
||||||
// Absolute distance from Zero - copy value from heights<float>
|
// Absolute distance from Zero - copy value from heights<float>
|
||||||
// [[deprecated]] Use index to layers insted of adress from item
|
float print_z; // [in mm]
|
||||||
double print_z; // [in mm]
|
|
||||||
|
|
||||||
// data for one expolygon
|
// data for one expolygon
|
||||||
LayerParts parts;
|
LayerParts parts;
|
||||||
@ -122,10 +136,10 @@ struct SupportPointGeneratorData
|
|||||||
{
|
{
|
||||||
// Input slices of mesh
|
// Input slices of mesh
|
||||||
std::vector<ExPolygons> slices;
|
std::vector<ExPolygons> slices;
|
||||||
// Same size as slices
|
|
||||||
std::vector<float> heights;
|
|
||||||
|
|
||||||
// link to slices
|
// Keep information about layer and its height
|
||||||
|
// and connection between layers for its part
|
||||||
|
// NOTE: contain links into slices
|
||||||
Layers layers;
|
Layers layers;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -147,7 +161,7 @@ using StatusFunction= std::function<void(int)>;
|
|||||||
/// <returns>Data prepared for generate support points</returns>
|
/// <returns>Data prepared for generate support points</returns>
|
||||||
SupportPointGeneratorData prepare_generator_data(
|
SupportPointGeneratorData prepare_generator_data(
|
||||||
std::vector<ExPolygons> &&slices,
|
std::vector<ExPolygons> &&slices,
|
||||||
std::vector<float> &&heights,
|
const std::vector<float> &heights,
|
||||||
ThrowOnCancel throw_on_cancel,
|
ThrowOnCancel throw_on_cancel,
|
||||||
StatusFunction statusfn
|
StatusFunction statusfn
|
||||||
);
|
);
|
||||||
|
@ -678,45 +678,47 @@ RENDER_AGAIN:
|
|||||||
else { // not in editing mode:
|
else { // not in editing mode:
|
||||||
m_imgui->disabled_begin(!is_input_enabled());
|
m_imgui->disabled_begin(!is_input_enabled());
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::Text("Distribution depends on './resources/data/sla_support.svg'\ninstruction for edit are in file");
|
||||||
ImGuiPureWrap::text(m_desc.at("minimal_distance"));
|
|
||||||
ImGui::SameLine(settings_sliders_left);
|
|
||||||
ImGui::PushItemWidth(window_width - settings_sliders_left);
|
|
||||||
|
|
||||||
std::vector<const ConfigOption*> opts = get_config_options({"support_points_density_relative", "support_points_minimal_distance"});
|
//ImGui::AlignTextToFramePadding();
|
||||||
float density = static_cast<const ConfigOptionInt*>(opts[0])->value;
|
//ImGuiPureWrap::text(m_desc.at("minimal_distance"));
|
||||||
float minimal_point_distance = static_cast<const ConfigOptionFloat*>(opts[1])->value;
|
//ImGui::SameLine(settings_sliders_left);
|
||||||
|
//ImGui::PushItemWidth(window_width - settings_sliders_left);
|
||||||
|
|
||||||
m_imgui->slider_float("##minimal_point_distance", &minimal_point_distance, 0.f, 20.f, "%.f mm");
|
//std::vector<const ConfigOption*> opts = get_config_options({"support_points_density_relative", "support_points_minimal_distance"});
|
||||||
bool slider_clicked = m_imgui->get_last_slider_status().clicked; // someone clicked the slider
|
//float density = static_cast<const ConfigOptionInt*>(opts[0])->value;
|
||||||
bool slider_edited = m_imgui->get_last_slider_status().edited; // someone is dragging the slider
|
//float minimal_point_distance = static_cast<const ConfigOptionFloat*>(opts[1])->value;
|
||||||
bool slider_released = m_imgui->get_last_slider_status().deactivated_after_edit; // someone has just released the slider
|
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
//m_imgui->slider_float("##minimal_point_distance", &minimal_point_distance, 0.f, 20.f, "%.f mm");
|
||||||
ImGuiPureWrap::text(m_desc.at("points_density"));
|
//bool slider_clicked = m_imgui->get_last_slider_status().clicked; // someone clicked the slider
|
||||||
ImGui::SameLine(settings_sliders_left);
|
//bool slider_edited = m_imgui->get_last_slider_status().edited; // someone is dragging the slider
|
||||||
|
//bool slider_released = m_imgui->get_last_slider_status().deactivated_after_edit; // someone has just released the slider
|
||||||
|
|
||||||
m_imgui->slider_float("##points_density", &density, 0.f, 200.f, "%.f %%");
|
//ImGui::AlignTextToFramePadding();
|
||||||
slider_clicked |= m_imgui->get_last_slider_status().clicked;
|
//ImGuiPureWrap::text(m_desc.at("points_density"));
|
||||||
slider_edited |= m_imgui->get_last_slider_status().edited;
|
//ImGui::SameLine(settings_sliders_left);
|
||||||
slider_released |= m_imgui->get_last_slider_status().deactivated_after_edit;
|
|
||||||
|
|
||||||
if (slider_clicked) { // stash the values of the settings so we know what to revert to after undo
|
//m_imgui->slider_float("##points_density", &density, 0.f, 200.f, "%.f %%");
|
||||||
m_minimal_point_distance_stash = minimal_point_distance;
|
//slider_clicked |= m_imgui->get_last_slider_status().clicked;
|
||||||
m_density_stash = density;
|
//slider_edited |= m_imgui->get_last_slider_status().edited;
|
||||||
}
|
//slider_released |= m_imgui->get_last_slider_status().deactivated_after_edit;
|
||||||
if (slider_edited) {
|
|
||||||
mo->config.set("support_points_minimal_distance", minimal_point_distance);
|
//if (slider_clicked) { // stash the values of the settings so we know what to revert to after undo
|
||||||
mo->config.set("support_points_density_relative", (int)density);
|
// m_minimal_point_distance_stash = minimal_point_distance;
|
||||||
}
|
// m_density_stash = density;
|
||||||
if (slider_released) {
|
//}
|
||||||
mo->config.set("support_points_minimal_distance", m_minimal_point_distance_stash);
|
//if (slider_edited) {
|
||||||
mo->config.set("support_points_density_relative", (int)m_density_stash);
|
// mo->config.set("support_points_minimal_distance", minimal_point_distance);
|
||||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Support parameter change"));
|
// mo->config.set("support_points_density_relative", (int)density);
|
||||||
mo->config.set("support_points_minimal_distance", minimal_point_distance);
|
//}
|
||||||
mo->config.set("support_points_density_relative", (int)density);
|
//if (slider_released) {
|
||||||
wxGetApp().obj_list()->update_and_show_object_settings_item();
|
// mo->config.set("support_points_minimal_distance", m_minimal_point_distance_stash);
|
||||||
}
|
// mo->config.set("support_points_density_relative", (int)m_density_stash);
|
||||||
|
// Plater::TakeSnapshot snapshot(wxGetApp().plater(), _L("Support parameter change"));
|
||||||
|
// mo->config.set("support_points_minimal_distance", minimal_point_distance);
|
||||||
|
// mo->config.set("support_points_density_relative", (int)density);
|
||||||
|
// wxGetApp().obj_list()->update_and_show_object_settings_item();
|
||||||
|
//}
|
||||||
|
|
||||||
bool generate = ImGuiPureWrap::button(m_desc.at("auto_generate"));
|
bool generate = ImGuiPureWrap::button(m_desc.at("auto_generate"));
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user