Commit 403aea7e authored by TOUZE Francois's avatar TOUZE Francois
Browse files

review TwissAction && redesign LayoutView

parent e7cb4f9b
......@@ -311,72 +311,72 @@ void elementBend::toJSON(json& j)
j["color"]= "#74B9FF";
// arc length (m)
j["parameters"]["A%length"]["displayName"] = "Arc length (m)";
j["parameters"]["A%length"]["value"] = length_;
j["parameters"]["A%length"]["type"] = "number";
j["parameters"]["A$length"]["displayName"] = "Arc length (m)";
j["parameters"]["A$length"]["value"] = length_;
j["parameters"]["A$length"]["type"] = "number";
// bend angle (rad)
j["parameters"]["B%angle"]["displayName"] = "Angle (rad)";
j["parameters"]["B$angle"]["displayName"] = "Angle (rad)";
if (vtr_[ 0 ].find("none") == std::string::npos ) {
j["parameters"]["B%angle"]["value"] = atof(vtr_[ 0 ].c_str());
j["parameters"]["B$angle"]["value"] = atof(vtr_[ 0 ].c_str());
} else {
j["parameters"]["B%angle"]["value"] = nullptr;
j["parameters"]["B$angle"]["value"] = nullptr;
}
j["parameters"]["B%angle"]["type"] = "number";
j["parameters"]["B$angle"]["type"] = "number";
// reference energy (MeV)
j["parameters"]["C%wref"]["displayName"] = "Reference energy (MeV)";
j["parameters"]["C$wref"]["displayName"] = "Reference energy (MeV)";
if (vtr_[ 2 ].find("none") == std::string::npos ) {
j["parameters"]["C%wref"]["value"] = atof(vtr_[ 2 ].c_str());
j["parameters"]["C$wref"]["value"] = atof(vtr_[ 2 ].c_str());
} else {
j["parameters"]["C%wref"]["value"] = nullptr;
j["parameters"]["C$wref"]["value"] = nullptr;
}
j["parameters"]["C%wref"]["type"] = "number";
j["parameters"]["C$wref"]["type"] = "number";
// entrance edge angle (rad)
j["parameters"]["D%e1"]["displayName"] = "Entrance edge angle (rad)";
j["parameters"]["D$e1"]["displayName"] = "Entrance edge angle (rad)";
if (vtr_[ 3 ].find("none") == std::string::npos ) {
j["parameters"]["D%e1"]["value"] = atof(vtr_[ 3 ].c_str());
j["parameters"]["D$e1"]["value"] = atof(vtr_[ 3 ].c_str());
} else {
j["parameters"]["D%e1"]["value"] = nullptr;
j["parameters"]["D$e1"]["value"] = nullptr;
}
j["parameters"]["D%e1"]["type"] = "number";
j["parameters"]["D$e1"]["type"] = "number";
// exit edge angle (rad)
j["parameters"]["E%e2"]["displayName"] = "Exit edge angle (rad)";
j["parameters"]["E$e2"]["displayName"] = "Exit edge angle (rad)";
if (vtr_[ 4 ].find("none") == std::string::npos ) {
j["parameters"]["E%e2"]["value"] = atof(vtr_[ 4 ].c_str());
j["parameters"]["E$e2"]["value"] = atof(vtr_[ 4 ].c_str());
} else {
j["parameters"]["E%e2"]["value"] = nullptr;
j["parameters"]["E$e2"]["value"] = nullptr;
}
j["parameters"]["E%e2"]["type"] = "number";
j["parameters"]["E$e2"]["type"] = "number";
// fringe field integral at entrance
j["parameters"]["F%f_int1"]["displayName"] = "Entrance fringe field";
j["parameters"]["F$f_int1"]["displayName"] = "Entrance fringe field";
if (vtr_[ 5 ].find("none") == std::string::npos ) {
j["parameters"]["F%f_int1"]["value"] = atof(vtr_[ 5 ].c_str());
j["parameters"]["F$f_int1"]["value"] = atof(vtr_[ 5 ].c_str());
} else {
j["parameters"]["F%f_int1"]["value"] = nullptr;
j["parameters"]["F$f_int1"]["value"] = nullptr;
}
j["parameters"]["F%f_int1"]["type"] = "number";
j["parameters"]["F$f_int1"]["type"] = "number";
// fringe field integral at exit
j["parameters"]["G%f_int2"]["displayName"] = "Exit fringe field";
j["parameters"]["G$f_int2"]["displayName"] = "Exit fringe field";
if (vtr_[ 6 ].find("none") == std::string::npos ) {
j["parameters"]["G%f_int2"]["value"] = atof(vtr_[ 6 ].c_str());
j["parameters"]["G$f_int2"]["value"] = atof(vtr_[ 6 ].c_str());
} else {
j["parameters"]["G%f_int2"]["value"] = nullptr;
j["parameters"]["G$f_int2"]["value"] = nullptr;
}
j["parameters"]["G%f_int2"]["type"] = "number";
j["parameters"]["G$f_int2"]["type"] = "number";
// half gap between poles (m)
j["parameters"]["H%h_gap"]["displayName"] = "Half-gap (m)";
j["parameters"]["H$h_gap"]["displayName"] = "Half-gap (m)";
if (vtr_[ 7 ].find("none") == std::string::npos ) {
j["parameters"]["H%h_gap"]["value"]= atof(vtr_[ 7 ].c_str());
j["parameters"]["H$h_gap"]["value"]= atof(vtr_[ 7 ].c_str());
} else {
j["parameters"]["H%h_gap"]["value"] = nullptr;
j["parameters"]["H$h_gap"]["value"] = nullptr;
}
j["parameters"]["H%h_gap"]["type"] = "number";
j["parameters"]["H$h_gap"]["type"] = "number";
}
void elementBend::fromJSON(json j)
......@@ -393,12 +393,12 @@ void elementBend::fromJSON(json j)
json::iterator z= j.find( "parameters" );
json::iterator kt;
kt= z->find( "A%length" )->find( "value" );
kt= z->find( "A$length" )->find( "value" );
if (kt->is_number()) length_= *kt;
vector<string> v(8,"none");
kt= z->find( "B%angle" );
kt= z->find( "B$angle" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) {
......@@ -409,37 +409,37 @@ void elementBend::fromJSON(json j)
}
}
kt= z->find( "C%wref" );
kt= z->find( "C$wref" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) v.at( 2 )= mixedTools::doubleToString( *zz );
}
kt= z->find( "D%e1" );
kt= z->find( "D$e1" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) v.at( 3 )= mixedTools::doubleToString( *zz );
}
kt= z->find( "E%e2" );
kt= z->find( "E$e2" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) v.at( 4 )= mixedTools::doubleToString( *zz );
}
kt= z->find( "F%f_int1" );
kt= z->find( "F$f_int1" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) v.at( 5 )= mixedTools::doubleToString( *zz );
}
kt= z->find( "G%f_int2" );
kt= z->find( "G$f_int2" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) v.at( 6 )= mixedTools::doubleToString( *zz );
}
kt= z->find( "H%h_gap" );
kt= z->find( "H$h_gap" );
if (kt != z->end()) {
auto zz = kt->find( "value" );
if (zz->is_number()) v.at( 7 )= mixedTools::doubleToString( *zz );
......
<template>
<aside class="elements-area">
<div class="elements-area-body">
<div id="scene">
<v-stage v-if="elementsList.length" :config="configKonva">
<v-layer>
<div v-for="(element, index) in elementsList" v-bind:key="index">
<v-line v-if="index < elementsList.length - 1" :config="getConfigLine(element, index)"></v-line>
<v-rect v-if="element.type !== DRIFT" :config="getConfigRect(element)"></v-rect>
<v-image v-if="element.type !== DRIFT" :config="getImgConfig(element)"></v-image>
</div>
</v-layer>
</v-stage>
</div>
</div>
</aside>
<aside class="elements-area">
<!-- div class="command">
<button @click="zoom(1)">ZoomIn</button>
<button @click="zoom(-1)">ZoomOut</button>
</div -->
<div id="scene">
<!-- v-stage v-if="elementsList.length" :config="configKonva" -->
<v-stage :config="configKonva">
<v-layer>
<div v-for="(e,index) in eList" v-bind:key="index">
<!-- v-line v-if="index < eList.length-2 && e.type === DRIFT"
:config="getConfigLine(e,index)">
</v-line -->
<v-rect v-if="e.type === BEAM"
:config="getConfigRect(e,index)">
</v-rect>
<v-line v-if="e.type === DRIFT"
:config="getConfigLine(e,index)">
</v-line>
<v-rect v-if="e.type === QUAD"
:config="getConfigRect(e,index)">
</v-rect>
<v-rect v-if="e.type === SEXT"
:config="getConfigRect(e,index)">
</v-rect>
<!-- v-line v-if="e.type === BEND"
:config="getConfigArc(e,index)">
</v-line -->
<!-- v-circle v-if="e.type === BEND"
:config="getConfigCircle(e,index)">
</v-circle -->
<v-circle v-if="e.type === BEND"
:config="getConfigOMEGA(e,index)">
</v-circle>
<v-arc v-if="e.type === BEND"
:config="getConfigRAF(e,index)">
</v-arc>
<v-circle v-if="e.type === BEND"
:config="getConfigOUT(e,index)">
</v-circle>
<!-- v-image v-if="element.type !== DRIFT" :config="getImgConfig(element)"></v-image -->
</div>
</v-layer>
</v-stage>
</div>
<!-- /div -->
</aside>
</template>
<script>
import _ from 'lodash';
import TreeModel from 'tree-model'
import Vue from 'vue';
import VueKonva from 'vue-konva'
Vue.use(VueKonva);
import panzoom from 'panzoom'
import TreeModel from 'tree-model'
import { DRIFT } from '@/utils/constants/element-ids.js'
Vue.use(VueKonva);
import {BEAM,DRIFT,BEND,QUAD,SEXT} from '@/utils/constants/element-ids.js'
const RECT_WIDTH = 25;
const RECT_HEIGHT = 25;
const MIN_GAP = 25;
const width = window.innerWidth;
const height = window.innerHeight;
export default {
props: ['treeModel', 'selectedElement'],
watch: {
treeModel: function(newValue, oldValue) {
this.x = 5600;
this.y = 5500;
this.elementsList = this.$getElementList();
}
},
props: ['treeModel', 'selectedElement'],
data () {
return {
tree: null,
x: 5600,
y: 5500,
elementsList: [],
maxDrift: 0,
configKonva: {
width: 10000,
height: 10000
},
DRIFT
tree: null,
eList: [],
BEAM,
DRIFT,
BEND,
QUAD,
SEXT,
pourVoir: [],
xx: 5600,
xy: 5500,
x: 300,
y: 150,
maxDrift: 0,
configKonva: {
width: width, //4*width,
height: 3*height //3*height
}
}
},
},
watch: {
treeModel: function(newValue, oldValue) {
console.log("WATCH")
this.x = 700; //5600;
this.y = 150; //500;
this.eList = this.$getElementList();
}
},
methods: {
$getMaxDrift (elements) {
let maxDrift = 0.000001
elements.forEach(element => {
if (element.type === DRIFT && element.parameters && element.parameters.length && element.parameters.length.value) {
if (maxDrift < element.parameters.length.value) {
maxDrift = element.parameters.length.value
}
}
})
return maxDrift
},
getConfigRect: function(element) {
const config = {
x: element.x - (RECT_WIDTH / 2),
y: element.y - (RECT_HEIGHT / 2),
width: RECT_WIDTH,
height: RECT_HEIGHT,
fill: element.color
};
if (this.selectedElement && this.selectedElement.id === element.id) {
config.stroke = '#3e91ce';
config.strokeWidth = 6;
} else {
config.stroke = 'white';
config.strokeWidth = 0;
}
return config;
},
getImgConfig: function(element) {
const conifgImage = {
x: element.x - (RECT_WIDTH * 0.28),
$getElementList: function () {
const eList = this.$walTreeAndSelectElement();
const xyList = this.MYcalculateCoordinates(eList);
return xyList;
},
$walTreeAndSelectElement: function() {
const nodesList = [];
const treeModel = new TreeModel({
childrenPropertyName: 'elements'
});
this.tree = treeModel.parse({id: 'root', elements: this.treeModel});
this.tree.walk((node) => {
if (node.model.category === 'element') {
nodesList.push(node.model);
}
});
return nodesList;
},
MYcalculateCoordinates: function(eList) {
this.maxDrift = this.$getMaxDrift(eList);
let theta = 0;
let alfa = 0;
let xcoor = 0;
let ycoor = 0;
let eType = 'unknown';
let driftGap = 1.0; // <= ATTENTION pour index=0
var array = [] // <= pour le v-for
this.pourVoir = [] // <= gestion des elements
eList.forEach((e,index) => {
console.log("ETYPE: ",e.type)
if (index > 0 && eType === 'bend') {
// si l'element (e) est après un "bend" calcul de l'image du point d'entrée par la rotation d'angle alfa qui sera le point de départ de (e)
this.x += xcoor*Math.cos(alfa)+ycoor*Math.sin(alfa)-xcoor;
this.y += xcoor*Math.sin(alfa)-ycoor*Math.cos(alfa)+ycoor;
theta = (theta+alfa) % (2*Math.PI);
} else {
this.x += driftGap*Math.cos(theta);
this.y += driftGap*Math.sin(theta);
}
// memoire du type (e) pour detecter si un élément est précédé d'un "bend"
eType = e.type;
// calcul en pixels de longueur ou rayon
driftGap = this.$calculDriftGap(e);
console.log("DRIFTGAP[",index,"] => ",driftGap,eType)
if (e.type === 'bend') {
if (_.get(e,'parameters.B$angle.value')) {
// alfa est l'angle de la rotation et xcoor,ycoor le centre
alfa = e.parameters.B$angle.value
xcoor = driftGap*Math.sin(theta);
ycoor = driftGap*Math.cos(theta);
//theta = (theta+e.parameters.B$angle.value) % (2*Math.PI);
}
}
//console.log("XY[",index,"] => x:",this.x,",y:",this.y,", theta:", theta,", alfa:",alfa)
array.push({x: this.x, y: this.y, theta: theta, ...e});
this.pourVoir.push({eType: e.type, x: this.x, y: this.y, theta: theta, delta: driftGap})
})
// "bidouille" pour le tracé du dernier element
// and add the last value of eList
this.x += driftGap*Math.cos(theta);
this.y += driftGap*Math.sin(theta);
this.pourVoir.push({eType: eType, x: this.x, y: this.y, theta: theta, delta: driftGap})
return array;
},
$calculateCoordinates: function(eList) { // not used
console.log("ELIST: ",eList)
let angle = 0;
let driftGap = 0;
this.maxDrift = this.$getMaxDrift(eList);
console.log("MAX => ",this.maxDrift)
this.pourVoir = [];
var array = []
array = eList.map((e,index) => {
console.log("ETYPE: ",e.type)
this.x = this.$getX(e.type, angle, driftGap, index);
this.y = this.$getY(e.type, angle, driftGap);
//console.log("XY[",index,"] => ",this.x," & ",this.y)
if (e.type === 'bend') {
if (_.get(e, 'parameters.B$angle.value')) {
angle = (angle+e.parameters.B$angle.value) % (2*Math.PI);
}
//console.log("ANGLE: ",angle)
driftGap = this.$calculDriftGap(e);
let xcoor = this.$getX(e.type, angle, driftGap, index);
let ycoor = this.$getY(e.type, angle, driftGap);
this.pourVoir.push({id: e.id, xin: this.x, yin: this.y, xout: xcoor, yout: ycoor})
}
driftGap = this.$calculDriftGap(e);
//console.log("GAP[",index,"]=> ",driftGap)
return { x: this.x, y: this.y, alfa: angle, ...e};
});
// return the last value of eList
const item = eList[eList.length-1];
console.log("LAST: ", item)
driftGap = this.$calculDriftGap(item);
this.x = this.$getX(e.type, angle, driftGap, index);
this.y = this.$getY(e.type, angle, driftGap);
return array
},
$getMaxDrift (eList) {
let maxDrift = 0.000001
eList.forEach(e => {
if (e.type === DRIFT && e.parameters && e.parameters.length && e.parameters.length.value) {
if (maxDrift < e.parameters.length.value) {
maxDrift = e.parameters.length.value
}
}
})
return maxDrift
},
$getX: function(type,angle,driftGap = 0,index) { // not used
// If element type is equal to DRIFT, we delete GAP in order that elements between him are glued if drift length is 0
let angleDeg = (180 * angle) / (Math.PI)
let a = this.x + Math.cos(angle);
let b = this.x + driftGap*Math.cos(angle);
return index == 0 ? (a) : (b);
},
$getY: function(type,angle,driftGap = 0) { // not used
// If element type is equal to DRIFT, we delete GAP in order that elements between him are glued if drift length is 0
let angleDeg = (180 * angle) / (Math.PI)
return (this.y + driftGap*Math.sin(angle))
},
$calculDriftGap: function(element) {
if (_.has(element,'parameters.length.value')) {
return this.$convertMeterToPixel(element.parameters.length.value);
} else if (_.has(element,'parameters.A$length.value') && _.has(element,'parameters.B$angle.value')) {
let long = element.parameters.A$length.value;
let alfa = element.parameters.B$angle.value;
return this.$convertMeterToPixel(long/alfa);
}
//else if (_.has(element, 'parameters.length.radius') && _.has(element, 'parameters.length.angle')) {
//return this.$convertMeterToPixel(element.parameters.radius.value * element.parameters.angle.value);
//}
else {
return 0;
}
},
$convertMeterToPixel: function(length) {
// ATTENTION ici j'ai remplacé 250 (valeur de CGI) par 100
return (+length / (this.maxDrift || 1)) * 100; //250
},
getConfigLine: function(e,index) {
// tracé du segment de {x, y} à {nextX, nextY}
const {x, y} = this.pourVoir[index];
const {x: nextX, y: nextY} = this.pourVoir[index + 1];
//console.log("V-LINE[", index, "]:", x,y,nextX,nextY)
const config = {
points: [x, y, nextX, nextY],
lineJoin: 'round',
//dash: [10, 8]
}