增加 libavoid

This commit is contained in:
锦恢 2024-12-26 23:56:27 +08:00
parent b8bbc0e290
commit 37be4cbb0e
18 changed files with 3789 additions and 18 deletions

BIN
public/avoid.wasm Normal file

Binary file not shown.

View File

@ -23,6 +23,7 @@
const skinBinary = await r2.arrayBuffer(); const skinBinary = await r2.arrayBuffer();
return [ netJson, skinBinary ]; return [ netJson, skinBinary ];
} }
window.avoidWasm = 'avoid.wasm';
</script> </script>
</head> </head>

View File

@ -10,8 +10,13 @@ import Render from '@/components/render';
import RightNav from '@/components/right-nav.vue'; import RightNav from '@/components/right-nav.vue';
import { onMounted, watch } from 'vue'; import { onMounted, watch } from 'vue';
import { setDefaultCss } from './hook/css'; import { setDefaultCss } from './hook/css';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
import { AvoidLib } from '@/lib/avoid';
import { globalLookup, globalSetting } from './hook/global'; import { globalLookup, globalSetting } from './hook/global';
import { ElLoading } from 'element-plus';
// globalSetting localStorage // globalSetting localStorage
watch( watch(
@ -27,19 +32,56 @@ onMounted(async () => {
// css // css
setDefaultCss(); setDefaultCss();
const loading = new ElLoading.service({
lock: true,
text: t('loading'),
background: 'rgba(0, 0, 0, 0.7)'
});
// netlist json // netlist json
const [ netJson, skinBinary ] = await window.readNetFile(); const [ netJson, skinBinary ] = await window.readNetFile();
// avoid lib
const wasmBinaryResponse = await fetch(window.avoidWasm);
const wasmBinary = await wasmBinaryResponse.arrayBuffer();
await AvoidLib.load({ wasmBinary });
const Avoid = AvoidLib.getInstance();
globalLookup.Avoid = Avoid;
const router = new Avoid.Router(Avoid.PolyLineRouting);
const srcPt = new Avoid.Point(1.2, 0.5);
const dstPt = new Avoid.Point(1.5, 4);
const srcConnEnd = new Avoid.ConnEnd(srcPt);
const dstConnEnd = new Avoid.ConnEnd(dstPt);
const connRef = new Avoid.ConnRef(router);
function connCallback(connRefPtr) {
const connRef = Avoid.wrapPointer(connRefPtr, Avoid.ConnRef);
console.log(`Connector ${connRef.id()} needs rerouting!`);
const route = connRef.displayRoute();
console.log('New path: ');
for (let i = 0; i < route.size(); i++) {
console.log(`(${route.get_ps(i).x}, ${route.get_ps(i).y})`);
}
}
connRef.setCallback(connCallback, connRef);
// Force inital callback:
router.processTransaction();
const render = globalLookup.netlistRender; const render = globalLookup.netlistRender;
const skinManager = globalLookup.skinManager; const skinManager = globalLookup.skinManager;
skinManager.load(skinBinary); skinManager.load(skinBinary);
render.load(netJson); render.load(netJson);
const layout = await render.createLayout(); const layout = await render.createLayout();
const svg = await render.render(layout, '#netlist'); const svg = await render.render(layout, '#netlist');
console.log(svg); loading.close();
}); });
</script> </script>

View File

@ -22,6 +22,10 @@ export const globalLookup = {
*/ */
netlistRender: new NetlistRender(), netlistRender: new NetlistRender(),
/**
* @type {Avoid}
*/
Avoid: undefined
}; };
function loadSetting() { function loadSetting() {

View File

@ -239,6 +239,9 @@ async function dragStart(event, manager, rootRender) {
context.elkGraph.children = nodes; context.elkGraph.children = nodes;
context.elkGraph.edges = edges; context.elkGraph.edges = edges;
context.elkGraph.layoutOptions = {
'elk.algorithm': 'layered'
};
} }
/** /**

View File

@ -9,6 +9,7 @@ import { InstantiationRender } from './instantiation';
import { CellRender } from './cell'; import { CellRender } from './cell';
import { ConnectionRender } from './connection'; import { ConnectionRender } from './connection';
import { WireRender } from './wire'; import { WireRender } from './wire';
import { pinkLog } from '../utils';
export class NetlistRender { export class NetlistRender {
/** /**
@ -113,10 +114,8 @@ export class NetlistRender {
const start = performance.now(); const start = performance.now();
const layoutGraph = await this.elk.layout(graph); const layoutGraph = await this.elk.layout(graph);
const timecost = (performance.now() - start).toFixed(3); const timecost = (performance.now() - start).toFixed(3);
console.log(
`%c 布局计算耗时 ${timecost} ms`, pinkLog(`布局计算耗时 ${timecost} ms`);
'background-color: #CB81DA; color: white; padding: 3px; border-radius: 3px;'
);
return layoutGraph; return layoutGraph;
} }

5
src/hook/utils.js Normal file
View File

@ -0,0 +1,5 @@
const pinkLogStyle = 'background-color: #CB81DA; color: white; padding: 3px; border-radius: 3px;';
export function pinkLog(message) {
console.log('%c' + message, pinkLogStyle);
}

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "انقر + اسحب", "usermanual.click-move": "انقر + اسحب",
"usermanual.move-view": "عرض الجوال", "usermanual.move-view": "عرض الجوال",
"usermanual.scale-view": "تكبير/تصغير العرض", "usermanual.scale-view": "تكبير/تصغير العرض",
"usermanual.scale-view-more": "تكبير العرض (مقياس أكبر)" "usermanual.scale-view-more": "تكبير العرض (مقياس أكبر)",
"loading": "جاري التحميل"
} }

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "Klicken + Ziehen", "usermanual.click-move": "Klicken + Ziehen",
"usermanual.move-view": "Mobile Ansicht", "usermanual.move-view": "Mobile Ansicht",
"usermanual.scale-view": "Ansicht zoomen", "usermanual.scale-view": "Ansicht zoomen",
"usermanual.scale-view-more": "Ansicht vergrößern (größerer Maßstab)" "usermanual.scale-view-more": "Ansicht vergrößern (größerer Maßstab)",
"loading": "Laden"
} }

File diff suppressed because one or more lines are too long

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "Cliquer + Glisser", "usermanual.click-move": "Cliquer + Glisser",
"usermanual.move-view": "Vue mobile", "usermanual.move-view": "Vue mobile",
"usermanual.scale-view": "Zoom de la vue", "usermanual.scale-view": "Zoom de la vue",
"usermanual.scale-view-more": "Zoom de la vue (échelle plus grande)" "usermanual.scale-view-more": "Zoom de la vue (échelle plus grande)",
"loading": "Chargement"
} }

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "クリック + ドラッグ", "usermanual.click-move": "クリック + ドラッグ",
"usermanual.move-view": "モバイル表示", "usermanual.move-view": "モバイル表示",
"usermanual.scale-view": "ビューのズーム", "usermanual.scale-view": "ビューのズーム",
"usermanual.scale-view-more": "ビューのズーム(より大きなスケール)" "usermanual.scale-view-more": "ビューのズーム(より大きなスケール)",
"loading": "読み込み中"
} }

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "클릭 + 드래그", "usermanual.click-move": "클릭 + 드래그",
"usermanual.move-view": "모바일 보기", "usermanual.move-view": "모바일 보기",
"usermanual.scale-view": "보기 확대/축소", "usermanual.scale-view": "보기 확대/축소",
"usermanual.scale-view-more": "보기 확대 (더 큰 스케일)" "usermanual.scale-view-more": "보기 확대 (더 큰 스케일)",
"loading": "로딩 중"
} }

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "Клик + Перетаскивание", "usermanual.click-move": "Клик + Перетаскивание",
"usermanual.move-view": "Мобильный вид", "usermanual.move-view": "Мобильный вид",
"usermanual.scale-view": "Масштабирование вида", "usermanual.scale-view": "Масштабирование вида",
"usermanual.scale-view-more": "Масштабирование вида (больший масштаб)" "usermanual.scale-view-more": "Масштабирование вида (больший масштаб)",
"loading": "Загрузка"
} }

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "点击 + 拖动", "usermanual.click-move": "点击 + 拖动",
"usermanual.move-view": "移动视图", "usermanual.move-view": "移动视图",
"usermanual.scale-view": "视图缩放", "usermanual.scale-view": "视图缩放",
"usermanual.scale-view-more": "视图缩放(尺度更大)" "usermanual.scale-view-more": "视图缩放(尺度更大)",
"loading": "加载中"
} }

View File

@ -14,5 +14,6 @@
"usermanual.click-move": "點擊 + 拖動", "usermanual.click-move": "點擊 + 拖動",
"usermanual.move-view": "移動視圖", "usermanual.move-view": "移動視圖",
"usermanual.scale-view": "視圖縮放", "usermanual.scale-view": "視圖縮放",
"usermanual.scale-view-more": "視圖縮放(尺度更大)" "usermanual.scale-view-more": "視圖縮放(尺度更大)",
"loading": "加載中"
} }

130
src/lib/avoid.doc.js Normal file
View File

@ -0,0 +1,130 @@
/**
* Represents a point with x and y coordinates.
* @typedef {Object} Point
* @property {number} x - The x-coordinate.
* @property {number} y - The y-coordinate.
*/
/**
* Represents a router for managing shapes and connectors.
* @typedef {Object} Router
* @property {function(number): void} processTransaction - Processes the current transaction.
* @property {function(): void} printInfo - Prints router information.
* @property {function(ConnRef): void} deleteConnector - Deletes a connector.
* @property {function(ShapeRef, Polygon): void} moveShape - Moves a shape to a new polygon.
* @property {function(ShapeRef, number, number): void} moveShape - Moves a shape by a specified offset.
* @property {function(ShapeRef): void} deleteShape - Deletes a shape.
* @property {function(number, number): void} setRoutingParameter - Sets a routing parameter.
* @property {function(number, boolean): void} setRoutingOption - Sets a routing option.
*/
/**
* Represents a polyline.
* @typedef {Object} PolyLine
* @property {function(): number} size - Returns the number of points in the polyline.
* @property {function(number): Point} get_ps - Returns the point at the specified index.
*/
/**
* Represents a connection endpoint.
* @typedef {Object} ConnEnd
* @property {function(Point): void} constructor - Creates a connection endpoint from a point.
* @property {function(ShapeRef, number): void} constructor - Creates a connection endpoint from a shape reference.
* @property {function(JunctionRef, number): ConnEnd} createConnEndFromJunctionRef - Creates a connection endpoint from a junction reference.
*/
/**
* Represents a connector reference.
* @typedef {Object} ConnRef
* @property {function(Router): void} constructor - Creates a connector reference.
* @property {function(Router, ConnEnd, ConnEnd): void} constructor - Creates a connector reference with endpoints.
* @property {function(): PolyLine} displayRoute - Displays the route of the connector.
* @property {function(ConnEnd): void} setSourceEndpoint - Sets the source endpoint of the connector.
* @property {function(ConnEnd): void} setDestEndpoint - Sets the destination endpoint of the connector.
* @property {function(number): void} setRoutingType - Sets the routing type of the connector.
* @property {function(function(number): void, ConnRef): void} setCallback - Sets a callback for the connector.
* @property {function(boolean): void} setHateCrossings - Sets whether the connector hates crossings.
* @property {function(): boolean} doesHateCrossings - Returns whether the connector hates crossings.
*/
/**
* Enum for connection direction flags.
* @typedef {Object} ConnDirFlags
*/
/**
* Represents a shape connection pin.
* @typedef {Object} ShapeConnectionPin
* @property {function(ShapeRef, number, number, number, boolean, number, ConnDirFlags): void} constructor - Creates a shape connection pin.
* @property {function(JunctionRef, number, ConnDirFlags): void} constructor - Creates a shape connection pin from a junction reference.
* @property {function(number): void} setConnectionCost - Sets the connection cost.
* @property {function(boolean): void} setExclusive - Sets whether the pin is exclusive.
* @property {function(): boolean} isExclusive - Returns whether the pin is exclusive.
* @property {function(): ConnDirFlags} directions - Returns the visible directions.
* @property {function(): Point} position - Returns the position of the pin.
* @property {function(Point): void} updatePosition - Updates the position of the pin.
*/
/**
* Represents a junction reference.
* @typedef {Object} JunctionRef
* @property {function(Router, Point, number): void} constructor - Creates a junction reference.
* @property {function(): Point} position - Returns the position of the junction.
* @property {function(boolean): void} setPositionFixed - Sets whether the position is fixed.
* @property {function(): boolean} positionFixed - Returns whether the position is fixed.
* @property {function(): Point} recommendedPosition - Returns the recommended position.
*/
/**
* Represents a polygon.
* @typedef {Object} Polygon
*/
/**
* Represents a rectangle.
* @typedef {Object} Rectangle
* @property {function(Point, number, number): void} constructor - Creates a rectangle from a center point, width, and height.
* @property {function(Point, Point): void} constructor - Creates a rectangle from top-left and bottom-right points.
*/
/**
* Represents an obstacle.
* @typedef {Object} Obstacle
* @property {function(): number} id - Returns the ID of the obstacle.
* @property {function(): Polygon} polygon - Returns the polygon of the obstacle.
* @property {function(): Router} router - Returns the router of the obstacle.
* @property {function(): Point} position - Returns the position of the obstacle.
* @property {function(Polygon): void} setNewPoly - Sets a new polygon for the obstacle.
*/
/**
* Represents a shape reference.
* @typedef {Object} ShapeRef
* @property {function(Router, Polygon): void} constructor - Creates a shape reference.
*/
/**
* Represents the Avoid library.
* @typedef {Object} Avoid
* @property {number} PolyLineRouting - Polyline routing flag.
* @property {number} OrthogonalRouting - Orthogonal routing flag.
* @property {ConnEnd} ConnEnd - ConnEnd class.
* @property {ConnRef} ConnRef - ConnRef class.
* @property {Point} Point - Point class.
* @property {Rectangle} Rectangle - Rectangle class.
* @property {Router} Router - Router class.
* @property {Obstacle} Obstacle - Obstacle class.
* @property {ShapeRef} ShapeRef - ShapeRef class.
* @property {JunctionRef} JunctionRef - JunctionRef class.
* @property {function(any): void} destroy - Destroys an object.
* @property {function(any): number} getPointer - Gets the pointer of an object.
* @property {function(number, any): any} wrapPointer - Wraps a pointer into an object.
*/
/**
* Represents the Avoid library namespace.
* @typedef {Object} AvoidLib
* @property {Avoid | null} avoidLib - The Avoid library instance.
* @property {function(string): Promise<void>} load - Loads the Avoid library.
* @property {function(): Avoid} getInstance - Gets the Avoid instance.
*/

3578
src/lib/avoid.js Normal file

File diff suppressed because one or more lines are too long