aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--schemas/opcut.yaml2
-rw-r--r--src_js/common.js3
-rw-r--r--src_js/states.js1
-rw-r--r--src_js/vt.js21
-rw-r--r--src_py/opcut/common.py3
-rw-r--r--src_py/opcut/csp.py15
6 files changed, 40 insertions, 5 deletions
diff --git a/schemas/opcut.yaml b/schemas/opcut.yaml
index a6d5d0b..47e0a7f 100644
--- a/schemas/opcut.yaml
+++ b/schemas/opcut.yaml
@@ -11,6 +11,8 @@ definitions:
properties:
cut_width:
type: number
+ min_initial_usage:
+ type: boolean
panels:
type: object
patternProperties:
diff --git a/src_js/common.js b/src_js/common.js
index 1928624..c106f04 100644
--- a/src_js/common.js
+++ b/src_js/common.js
@@ -120,6 +120,8 @@ function createCalculateParams() {
if (cutWidth < 0)
throw 'Invalid cut width';
+ const minInitialUsage = r.get('form', 'min_initial_usage');
+
const panels = {};
for (const panel of r.get('form', 'panels')) {
if (!panel.name)
@@ -167,6 +169,7 @@ function createCalculateParams() {
return {
cut_width: cutWidth,
+ min_initial_usage: minInitialUsage,
panels: panels,
items: items
};
diff --git a/src_js/states.js b/src_js/states.js
index a696007..bf3584e 100644
--- a/src_js/states.js
+++ b/src_js/states.js
@@ -3,6 +3,7 @@ export const main = {
form: {
method: 'forward_greedy',
cut_width: 0.3,
+ min_initial_usage: false,
panels: [],
items: []
},
diff --git a/src_js/vt.js b/src_js/vt.js
index 8320f75..ce16d3d 100644
--- a/src_js/vt.js
+++ b/src_js/vt.js
@@ -68,7 +68,11 @@ function leftPanel() {
['label', 'Cut width'],
numberInput(r.get('form', 'cut_width'),
u.isNumber,
- val => r.set(['form', 'cut_width'], val))
+ val => r.set(['form', 'cut_width'], val)),
+ ['label'],
+ checkboxInput('Minimize initial panel usage',
+ r.get('form', 'min_initial_usage'),
+ val => r.set(['form', 'min_initial_usage'], val))
],
['div.content',
leftPanelPanels(),
@@ -240,7 +244,8 @@ function leftPanelItems() {
],
['td.col-rotate',
['div',
- checkboxInput(item.can_rotate,
+ checkboxInput(null,
+ item.can_rotate,
val => r.set([itemsPath, index, 'can_rotate'], val))
]
],
@@ -473,8 +478,8 @@ function numberInput(value, validator, onChange) {
}
-function checkboxInput(value, onChange) {
- return ['input', {
+function checkboxInput(label, value, onChange) {
+ const input = ['input', {
props: {
type: 'checkbox',
checked: value
@@ -483,6 +488,14 @@ function checkboxInput(value, onChange) {
change: evt => onChange(evt.target.checked)
}
}];
+
+ if (!label)
+ return input;
+
+ return ['label',
+ input,
+ ` ${label}`
+ ];
}
diff --git a/src_py/opcut/common.py b/src_py/opcut/common.py
index 90a8b00..9fbb7dd 100644
--- a/src_py/opcut/common.py
+++ b/src_py/opcut/common.py
@@ -29,6 +29,7 @@ class Item(typing.NamedTuple):
class Params(typing.NamedTuple):
cut_width: float
+ min_initial_usage: bool
panels: typing.List[Panel]
items: typing.List[Item]
@@ -81,6 +82,7 @@ def params_to_json(params: Params) -> json.Data:
"""Convert params to json serializable data specified by
``opcut://opcut.yaml#/definitions/params``"""
return {'cut_width': params.cut_width,
+ 'min_initial_usage': params.min_initial_usage,
'panels': {panel.id: {'width': panel.width,
'height': panel.height}
for panel in params.panels},
@@ -94,6 +96,7 @@ def params_from_json(data: json.Data) -> Params:
"""Convert json serializable data specified by
``opcut://opcut.yaml#/definitions/params`` to params"""
return Params(cut_width=data['cut_width'],
+ min_initial_usage=data.get('min_initial_usage', False),
panels=[Panel(id=k,
width=v['width'],
height=v['height'])
diff --git a/src_py/opcut/csp.py b/src_py/opcut/csp.py
index 43b8e1f..eb08314 100644
--- a/src_py/opcut/csp.py
+++ b/src_py/opcut/csp.py
@@ -145,4 +145,17 @@ def _fitness(result):
fitness -= (_fitness_K *
min(used_areas, default=0) * max(unused_areas, default=0) /
(total_area * total_area))
- return fitness
+
+ if not result.params.min_initial_usage:
+ return fitness
+
+ unused_initial_count = sum(1 for unused in result.unused
+ if _is_unused_initial(unused))
+ return (-unused_initial_count, fitness)
+
+
+def _is_unused_initial(unused):
+ return (unused.x == 0 and
+ unused.y == 0 and
+ unused.width == unused.panel.width and
+ unused.height == unused.panel.height)