kitchen-simulator 5.0.0-test.4 → 5.0.0-test.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -2
- package/src/@history.js +0 -3
- package/src/AppContext.js +0 -5
- package/src/KitchenConfigurator.jsx +0 -1517
- package/src/KitchenConfiguratorApp.jsx +0 -443
- package/src/actions/area-actions.js +0 -15
- package/src/actions/export.js +0 -38
- package/src/actions/groups-actions.js +0 -102
- package/src/actions/holes-actions.js +0 -152
- package/src/actions/items-actions.js +0 -393
- package/src/actions/lines-actions.js +0 -103
- package/src/actions/project-actions.js +0 -391
- package/src/actions/scene-actions.js +0 -44
- package/src/actions/user-actions.js +0 -75
- package/src/actions/vertices-actions.js +0 -34
- package/src/actions/viewer2d-actions.js +0 -79
- package/src/actions/viewer3d-actions.js +0 -32
- package/src/catalog/areas/area/planner-element.jsx +0 -43
- package/src/catalog/areas/area/textures/ceramic-tile.jpg +0 -0
- package/src/catalog/areas/area/textures/grass.jpg +0 -0
- package/src/catalog/areas/area/textures/parquet.jpg +0 -0
- package/src/catalog/areas/area/textures/strand-porcelain.jpg +0 -0
- package/src/catalog/areas/area/textures/tile1.jpg +0 -0
- package/src/catalog/back.png +0 -0
- package/src/catalog/catalog.js +0 -258
- package/src/catalog/doors.png +0 -0
- package/src/catalog/doorways.png +0 -0
- package/src/catalog/envMap/nx.hdr +0 -0
- package/src/catalog/envMap/ny.hdr +0 -0
- package/src/catalog/envMap/nz.hdr +0 -0
- package/src/catalog/envMap/px.hdr +0 -0
- package/src/catalog/envMap/py.hdr +0 -0
- package/src/catalog/envMap/pz.hdr +0 -0
- package/src/catalog/factories/area-factory-3d.js +0 -252
- package/src/catalog/factories/area-factory.jsx +0 -102
- package/src/catalog/factories/export.js +0 -9
- package/src/catalog/factories/wall-factory-3d.js +0 -296
- package/src/catalog/factories/wall-factory.jsx +0 -321
- package/src/catalog/holes/door-closet/planner-element.jsx +0 -251
- package/src/catalog/holes/door-double/door_double.png +0 -0
- package/src/catalog/holes/door-double/planner-element.jsx +0 -391
- package/src/catalog/holes/door-exterior/planner-element.jsx +0 -245
- package/src/catalog/holes/door-interior/planner-element.jsx +0 -256
- package/src/catalog/holes/door-panic/panicDoor.png +0 -0
- package/src/catalog/holes/door-panic/planner-element.jsx +0 -594
- package/src/catalog/holes/door-panic-double/panicDoorDouble.png +0 -0
- package/src/catalog/holes/door-panic-double/planner-element.jsx +0 -574
- package/src/catalog/holes/door-sliding/planner-element.jsx +0 -256
- package/src/catalog/holes/doorway-framed/planner-element.jsx +0 -169
- package/src/catalog/holes/doorway-frameless/planner-element.jsx +0 -116
- package/src/catalog/holes/gate/gate.jpg +0 -0
- package/src/catalog/holes/window-clear/planner-element.jsx +0 -181
- package/src/catalog/holes/window-clear/texture.png +0 -0
- package/src/catalog/holes/window-cross/planner-element.jsx +0 -180
- package/src/catalog/holes/window-cross/texture.png +0 -0
- package/src/catalog/holes/window-double-hung/planner-element.jsx +0 -366
- package/src/catalog/holes/window-double-hung/texture.png +0 -0
- package/src/catalog/holes/window-vertical/planner-element.jsx +0 -290
- package/src/catalog/holes/window-vertical/texture.png +0 -0
- package/src/catalog/lines/wall/planner-element.jsx +0 -73
- package/src/catalog/lines/wall/textures/bricks-normal.jpg +0 -0
- package/src/catalog/lines/wall/textures/bricks-normal2.jpg +0 -0
- package/src/catalog/lines/wall/textures/bricks.jpg +0 -0
- package/src/catalog/lines/wall/textures/bricks2.jpg +0 -0
- package/src/catalog/lines/wall/textures/bricks3.jpg +0 -0
- package/src/catalog/lines/wall/textures/morden-normal.jpg +0 -0
- package/src/catalog/lines/wall/textures/morden.jpg +0 -0
- package/src/catalog/lines/wall/textures/painted-normal.jpg +0 -0
- package/src/catalog/lines/wall/textures/painted.jpg +0 -0
- package/src/catalog/lines/wall/textures/plaster-normal.jpg +0 -0
- package/src/catalog/lines/wall/textures/plaster.jpg +0 -0
- package/src/catalog/lines/wall/wall.png +0 -0
- package/src/catalog/molding/molding-dcm/planner-element.jsx +0 -35
- package/src/catalog/molding/molding-dcm/texture.png +0 -0
- package/src/catalog/molding/molding-fbm/planner-element.jsx +0 -35
- package/src/catalog/molding/molding-fbm/texture.png +0 -0
- package/src/catalog/molding/molding-lrm/planner-element.jsx +0 -35
- package/src/catalog/molding/molding-lrm/texture.png +0 -0
- package/src/catalog/properties/export.js +0 -33
- package/src/catalog/properties/property-checkbox.jsx +0 -123
- package/src/catalog/properties/property-color.jsx +0 -52
- package/src/catalog/properties/property-enum.jsx +0 -87
- package/src/catalog/properties/property-hidden.jsx +0 -22
- package/src/catalog/properties/property-lenght-measure.jsx +0 -113
- package/src/catalog/properties/property-length-measure.jsx +0 -129
- package/src/catalog/properties/property-length-measure_hole.jsx +0 -110
- package/src/catalog/properties/property-number.jsx +0 -63
- package/src/catalog/properties/property-read-only.jsx +0 -37
- package/src/catalog/properties/property-string.jsx +0 -59
- package/src/catalog/properties/property-toggle.jsx +0 -51
- package/src/catalog/properties/shared-property-style.js +0 -13
- package/src/catalog/utils/FuseUtils.js +0 -61
- package/src/catalog/utils/exporter.js +0 -173
- package/src/catalog/utils/geom-utils.js +0 -301
- package/src/catalog/utils/item-loader.jsx +0 -2122
- package/src/catalog/utils/load-obj.js +0 -113
- package/src/catalog/utils/mtl-loader.js +0 -462
- package/src/catalog/utils/obj-loader.js +0 -544
- package/src/catalog/windows.png +0 -0
- package/src/class/FuseUtils.js +0 -61
- package/src/class/area.js +0 -159
- package/src/class/export.js +0 -37
- package/src/class/group.js +0 -565
- package/src/class/guide.js +0 -44
- package/src/class/hole.js +0 -1359
- package/src/class/item.js +0 -2050
- package/src/class/layer.js +0 -926
- package/src/class/line.js +0 -1780
- package/src/class/project.js +0 -875
- package/src/class/vertex.js +0 -409
- package/src/components/atoms/Snackbar/index.jsx +0 -43
- package/src/components/atoms/radio-button/index.jsx +0 -20
- package/src/components/atoms/radio-button/styles.js +0 -56
- package/src/components/button/MainButton.jsx +0 -157
- package/src/components/button/ToggleMeasureButton.jsx +0 -65
- package/src/components/catalog-view/catalog-breadcrumb.jsx +0 -53
- package/src/components/catalog-view/catalog-item.jsx +0 -229
- package/src/components/catalog-view/catalog-list.jsx +0 -173
- package/src/components/catalog-view/catalog-page-item.jsx +0 -110
- package/src/components/catalog-view/catalog-turn-back-page-item.jsx +0 -80
- package/src/components/configurator/custom-configurator.jsx +0 -77
- package/src/components/configurator/project-configurator.jsx +0 -120
- package/src/components/content.jsx +0 -136
- package/src/components/export.js +0 -36
- package/src/components/firstsetting/button/styles.js +0 -223
- package/src/components/firstsetting/export.js +0 -9
- package/src/components/firstsetting/firstsetting-content-button.jsx +0 -198
- package/src/components/firstsetting/firstsetting-toggle-button.jsx +0 -101
- package/src/components/firstsetting/firstsetting.jsx +0 -814
- package/src/components/footerbar/button/ControlButton.jsx +0 -43
- package/src/components/footerbar/button/DirectionButton.jsx +0 -54
- package/src/components/footerbar/button/DirectionPanSpinButton.jsx +0 -36
- package/src/components/footerbar/button/ToggleButton.jsx +0 -58
- package/src/components/footerbar/button/ToggleConvertButton.jsx +0 -48
- package/src/components/footerbar/button/ToggleMeasureButton.jsx +0 -33
- package/src/components/footerbar/button/styles.js +0 -217
- package/src/components/footerbar/export.js +0 -9
- package/src/components/footerbar/footer-content-button.jsx +0 -198
- package/src/components/footerbar/footer-toggle-button.jsx +0 -101
- package/src/components/footerbar/footerbar.jsx +0 -1103
- package/src/components/footerbar/styles.js +0 -263
- package/src/components/header/button/MenuButton.jsx +0 -46
- package/src/components/header/button/SaveButton.jsx +0 -54
- package/src/components/header/button/styles.js +0 -181
- package/src/components/header/export.js +0 -5
- package/src/components/header/header.jsx +0 -631
- package/src/components/header/header.style.css +0 -47
- package/src/components/header/styles.js +0 -320
- package/src/components/login/Login.js +0 -77
- package/src/components/login/LoginForm/index.js +0 -108
- package/src/components/login/Register.js +0 -83
- package/src/components/login/RegisterForm/index.js +0 -171
- package/src/components/login/jwtService.js +0 -201
- package/src/components/login/style.css +0 -158
- package/src/components/login/style.scss +0 -260
- package/src/components/molecules/slider/index.jsx +0 -15
- package/src/components/molecules/slider/styles.js +0 -0
- package/src/components/molecules/slider/styles.scss +0 -3
- package/src/components/myprojects/export.js +0 -5
- package/src/components/myprojects/index.jsx +0 -445
- package/src/components/myprojects/styles.js +0 -241
- package/src/components/sidebar/custom-accordion.jsx +0 -48
- package/src/components/sidebar/export.js +0 -15
- package/src/components/sidebar/panel-element-editor/attributes-editor/attributes-editor.jsx +0 -73
- package/src/components/sidebar/panel-element-editor/attributes-editor/confirm-popup.jsx +0 -101
- package/src/components/sidebar/panel-element-editor/attributes-editor/hole-attributes-editor.jsx +0 -149
- package/src/components/sidebar/panel-element-editor/attributes-editor/item-attributes-editor.jsx +0 -316
- package/src/components/sidebar/panel-element-editor/attributes-editor/line-attributes-editor.jsx +0 -108
- package/src/components/sidebar/panel-element-editor/element-editor.jsx +0 -1070
- package/src/components/sidebar/panel-element-editor/multi-elements-editor.jsx +0 -0
- package/src/components/sidebar/panel-element-editor/panel-element-editor.jsx +0 -104
- package/src/components/sidebar/panel-element-editor/panel-multi-elements-editor.jsx +0 -155
- package/src/components/sidebar/panel-group-editor.jsx +0 -272
- package/src/components/sidebar/panel-groups.jsx +0 -310
- package/src/components/sidebar/panel-guides.jsx +0 -192
- package/src/components/sidebar/panel-layer-elements.jsx +0 -298
- package/src/components/sidebar/panel-layers.jsx +0 -381
- package/src/components/sidebar/panel.jsx +0 -71
- package/src/components/sidebar/sidebar.jsx +0 -106
- package/src/components/sidebar/toolbar-panel.jsx +0 -139
- package/src/components/sign/export.js +0 -7
- package/src/components/sign/main/index.jsx +0 -523
- package/src/components/sign/main/styles.js +0 -163
- package/src/components/style/button.jsx +0 -95
- package/src/components/style/cancel-button.jsx +0 -20
- package/src/components/style/content-container.jsx +0 -29
- package/src/components/style/content-title.jsx +0 -20
- package/src/components/style/delete-button.jsx +0 -23
- package/src/components/style/export.jsx +0 -48
- package/src/components/style/form-block.jsx +0 -13
- package/src/components/style/form-color-input.jsx +0 -27
- package/src/components/style/form-label.jsx +0 -15
- package/src/components/style/form-number-input.jsx +0 -196
- package/src/components/style/form-number-input_2.jsx +0 -191
- package/src/components/style/form-select.jsx +0 -38
- package/src/components/style/form-slider.jsx +0 -36
- package/src/components/style/form-submit-button.jsx +0 -23
- package/src/components/style/form-text-input.jsx +0 -65
- package/src/components/toolbar/button/ControlButton.jsx +0 -41
- package/src/components/toolbar/button/DirectionButton.jsx +0 -34
- package/src/components/toolbar/button/RightButton.jsx +0 -103
- package/src/components/toolbar/button/ToggleButton.jsx +0 -41
- package/src/components/toolbar/button/index.jsx +0 -55
- package/src/components/toolbar/button/styles.js +0 -127
- package/src/components/toolbar/components/DoorStyleMenu.jsx +0 -103
- package/src/components/toolbar/components/Pricing.jsx +0 -126
- package/src/components/toolbar/components/ReviewForQuote.jsx +0 -635
- package/src/components/toolbar/export.js +0 -21
- package/src/components/toolbar/main/Alert.js +0 -122
- package/src/components/toolbar/main/TakePictureModal.jsx +0 -104
- package/src/components/toolbar/main/confirm-popup.jsx +0 -99
- package/src/components/toolbar/main/index.jsx +0 -5687
- package/src/components/toolbar/main/lShaped.json +0 -311
- package/src/components/toolbar/main/longNarrow.json +0 -238
- package/src/components/toolbar/main/myComponents.js +0 -123
- package/src/components/toolbar/main/oRectangle.json +0 -220
- package/src/components/toolbar/main/rectangle.json +0 -238
- package/src/components/toolbar/main/style.css +0 -107
- package/src/components/toolbar/main/styles.js +0 -696
- package/src/components/toolbar/plugin-item.jsx +0 -123
- package/src/components/toolbar/popup/appliance/appliance-category/index.jsx +0 -73
- package/src/components/toolbar/popup/appliance/choose-appliance/index.jsx +0 -102
- package/src/components/toolbar/popup/appliance/index.jsx +0 -83
- package/src/components/toolbar/popup/autosaveprompt/index.jsx +0 -150
- package/src/components/toolbar/popup/autosaveprompt/styles.css +0 -64
- package/src/components/toolbar/popup/autosaveprompt/styles.js +0 -40
- package/src/components/toolbar/popup/cabinet/cabinet-category/index.jsx +0 -73
- package/src/components/toolbar/popup/cabinet/choose-product/index.jsx +0 -119
- package/src/components/toolbar/popup/cabinet/index.jsx +0 -85
- package/src/components/toolbar/popup/doorStyle/choose-style/index.jsx +0 -63
- package/src/components/toolbar/popup/doorStyle/index.jsx +0 -71
- package/src/components/toolbar/popup/doorStyle/style-category/index.jsx +0 -139
- package/src/components/toolbar/popup/downloadsummary/downloadSummaryContext.js +0 -2
- package/src/components/toolbar/popup/downloadsummary/downloadSummaryTemp.jsx +0 -157
- package/src/components/toolbar/popup/downloadsummary/index.jsx +0 -643
- package/src/components/toolbar/popup/downloadsummary/show2D/show2DView.jsx +0 -51
- package/src/components/toolbar/popup/downloadsummary/show2D/viewer2DDownLoad.jsx +0 -175
- package/src/components/toolbar/popup/downloadsummary/show3D/show3DView.jsx +0 -283
- package/src/components/toolbar/popup/downloadsummary/show3D/viewer3DDownLoad.jsx +0 -2257
- package/src/components/toolbar/popup/downloadsummary/showCabinetInfo.js +0 -93
- package/src/components/toolbar/popup/downloadsummary/showElevation/showElevationView.jsx +0 -132
- package/src/components/toolbar/popup/downloadsummary/showElevation/viewer3DElevationDownload.jsx +0 -2198
- package/src/components/toolbar/popup/downloadsummary/showElevation/viewerElevationDownload.jsx +0 -152
- package/src/components/toolbar/popup/downloadsummary/showWarranty.jsx +0 -149
- package/src/components/toolbar/popup/downloadsummary/styles.css +0 -177
- package/src/components/toolbar/popup/downloadsummary/styles.js +0 -453
- package/src/components/toolbar/popup/finishingtouch/category/index.jsx +0 -34
- package/src/components/toolbar/popup/finishingtouch/index.jsx +0 -58
- package/src/components/toolbar/popup/finishingtouch/material-edit.jsx +0 -112
- package/src/components/toolbar/popup/finishingtouch/product/index.jsx +0 -116
- package/src/components/toolbar/popup/floorplan/choose-floor/confirm-popup.jsx +0 -101
- package/src/components/toolbar/popup/floorplan/choose-floor/index.jsx +0 -254
- package/src/components/toolbar/popup/floorplan/choose-floor/lShaped.json +0 -311
- package/src/components/toolbar/popup/floorplan/choose-floor/longNarrow.json +0 -238
- package/src/components/toolbar/popup/floorplan/choose-floor/oRectangle.json +0 -220
- package/src/components/toolbar/popup/floorplan/choose-floor/rectangle.json +0 -238
- package/src/components/toolbar/popup/floorplan/choose-floor/styles.js +0 -86
- package/src/components/toolbar/popup/floorplan/floor-category/index.jsx +0 -109
- package/src/components/toolbar/popup/floorplan/index.jsx +0 -60
- package/src/components/toolbar/popup/index.jsx +0 -241
- package/src/components/toolbar/popup/newproject/index.jsx +0 -59
- package/src/components/toolbar/popup/newproject/styles.css +0 -64
- package/src/components/toolbar/popup/newproject/styles.js +0 -41
- package/src/components/toolbar/popup/product/appliance.jsx +0 -54
- package/src/components/toolbar/popup/product/cabinetproduct.jsx +0 -15
- package/src/components/toolbar/popup/product/doorstyle.jsx +0 -58
- package/src/components/toolbar/popup/product/doorstyleproduct.jsx +0 -47
- package/src/components/toolbar/popup/product/floor.jsx +0 -36
- package/src/components/toolbar/popup/product/floorproduct.jsx +0 -42
- package/src/components/toolbar/popup/product/index.jsx +0 -36
- package/src/components/toolbar/popup/product/primary.jsx +0 -77
- package/src/components/toolbar/popup/product/productline.jsx +0 -93
- package/src/components/toolbar/popup/product/reviewItem.jsx +0 -427
- package/src/components/toolbar/popup/product/reviewMolding.jsx +0 -310
- package/src/components/toolbar/popup/product/style.css +0 -54
- package/src/components/toolbar/popup/product/styles.js +0 -260
- package/src/components/toolbar/popup/savedesign/FullPictureForm.jsx +0 -146
- package/src/components/toolbar/popup/savedesign/index.jsx +0 -495
- package/src/components/toolbar/popup/savedesign/savedesign.style.css +0 -16
- package/src/components/toolbar/popup/savedesign/styles.js +0 -151
- package/src/components/toolbar/popup/setDoorStyleOption/index.jsx +0 -87
- package/src/components/toolbar/popup/styles.js +0 -909
- package/src/components/toolbar/popup/submitforquote/AddToCartOptions.jsx +0 -192
- package/src/components/toolbar/popup/submitforquote/CustomerRequestsForm.jsx +0 -96
- package/src/components/toolbar/popup/submitforquote/SkipDesignerReview.jsx +0 -54
- package/src/components/toolbar/popup/submitforquote/StepDots.jsx +0 -25
- package/src/components/toolbar/popup/submitforquote/cart-choice.jsx +0 -116
- package/src/components/toolbar/popup/submitforquote/doorstyle-menus.js +0 -38
- package/src/components/toolbar/popup/submitforquote/index.jsx +0 -698
- package/src/components/toolbar/popup/submitforquote/styles.css +0 -105
- package/src/components/toolbar/popup/submitforquote/styles.js +0 -294
- package/src/components/toolbar/popup/submitprompt/index.jsx +0 -89
- package/src/components/toolbar/popup/submitprompt/styles.css +0 -64
- package/src/components/toolbar/popup/submitprompt/styles.js +0 -42
- package/src/components/toolbar/toolbar-button.jsx +0 -90
- package/src/components/toolbar/toolbar-load-button.jsx +0 -36
- package/src/components/toolbar/toolbar-save-button.jsx +0 -32
- package/src/components/tutorial-view/Modal.jsx +0 -584
- package/src/components/tutorial-view/style.css +0 -111
- package/src/components/tutorial-view/styles.js +0 -65
- package/src/components/viewer2d/area.jsx +0 -98
- package/src/components/viewer2d/export.js +0 -48
- package/src/components/viewer2d/grids/grid-horizontal-streak.jsx +0 -40
- package/src/components/viewer2d/grids/grid-streak.jsx +0 -32
- package/src/components/viewer2d/grids/grid-vertical-streak.jsx +0 -41
- package/src/components/viewer2d/grids/grids.jsx +0 -30
- package/src/components/viewer2d/group.jsx +0 -57
- package/src/components/viewer2d/item.jsx +0 -618
- package/src/components/viewer2d/layer.jsx +0 -214
- package/src/components/viewer2d/line.jsx +0 -1358
- package/src/components/viewer2d/ruler.jsx +0 -136
- package/src/components/viewer2d/rulerDist.jsx +0 -192
- package/src/components/viewer2d/rulerX.jsx +0 -141
- package/src/components/viewer2d/rulerY.jsx +0 -138
- package/src/components/viewer2d/scene.jsx +0 -94
- package/src/components/viewer2d/snap.jsx +0 -118
- package/src/components/viewer2d/state.jsx +0 -77
- package/src/components/viewer2d/utils.js +0 -195
- package/src/components/viewer2d/vertex.jsx +0 -76
- package/src/components/viewer2d/viewer2d.jsx +0 -1830
- package/src/components/viewer3d/camera-controls-module/camera-controls.module.js +0 -3078
- package/src/components/viewer3d/dcm.js +0 -226
- package/src/components/viewer3d/fbm.js +0 -383
- package/src/components/viewer3d/front3D.jsx +0 -63
- package/src/components/viewer3d/grid-creator.js +0 -25
- package/src/components/viewer3d/grids/grid-horizontal-streak.js +0 -41
- package/src/components/viewer3d/grids/grid-streak.js +0 -34
- package/src/components/viewer3d/grids/grid-vertical-streak.js +0 -42
- package/src/components/viewer3d/libs/first-person-controls.js +0 -70
- package/src/components/viewer3d/libs/helvetiker_regular.typeface.js +0 -1265
- package/src/components/viewer3d/libs/mtl-loader.js +0 -462
- package/src/components/viewer3d/libs/obj-loader.js +0 -653
- package/src/components/viewer3d/libs/orbit-controls.js +0 -945
- package/src/components/viewer3d/libs/pointer-lock-controls.js +0 -67
- package/src/components/viewer3d/lrm.js +0 -358
- package/src/components/viewer3d/model.js +0 -830
- package/src/components/viewer3d/pointer-lock-navigation.js +0 -140
- package/src/components/viewer3d/ruler-utils/itemRect.jsx +0 -91
- package/src/components/viewer3d/ruler-utils/layer3D.jsx +0 -528
- package/src/components/viewer3d/ruler-utils/ruler3D.jsx +0 -218
- package/src/components/viewer3d/ruler-utils/scene3D.jsx +0 -87
- package/src/components/viewer3d/ruler-utils/state3D.jsx +0 -25
- package/src/components/viewer3d/scene-creator.js +0 -5172
- package/src/components/viewer3d/three-memory-cleaner.js +0 -65
- package/src/components/viewer3d/viewer3d-first-person.js +0 -395
- package/src/components/viewer3d/viewer3d.js +0 -3376
- package/src/components/wizardstep/button/styles.js +0 -677
- package/src/components/wizardstep/export.js +0 -5
- package/src/components/wizardstep/index.jsx +0 -1372
- package/src/components/wizardstep/styles.js +0 -688
- package/src/components/wizardstep/wizardstep-content-button.jsx +0 -198
- package/src/components/wizardstep/wizardstep-toggle-button.jsx +0 -101
- package/src/constants.js +0 -731
- package/src/hooks/useCheckCart.js +0 -38
- package/src/hooks/useGetPricesBySku.js +0 -59
- package/src/hooks/useValidateToken.js +0 -181
- package/src/index.js +0 -32
- package/src/models.js +0 -541
- package/src/plugins/SVGLoader.js +0 -1991
- package/src/plugins/autosave.js +0 -39
- package/src/plugins/console-debugger.js +0 -36
- package/src/plugins/export.js +0 -11
- package/src/plugins/keyboard.js +0 -194
- package/src/reducers/areas-reducer.js +0 -13
- package/src/reducers/export.js +0 -39
- package/src/reducers/groups-reducer.js +0 -73
- package/src/reducers/holes-reducer.js +0 -125
- package/src/reducers/items-reducer.js +0 -286
- package/src/reducers/lines-reducer.js +0 -96
- package/src/reducers/project-reducer.js +0 -239
- package/src/reducers/reducer.js +0 -59
- package/src/reducers/scene-reducer.js +0 -41
- package/src/reducers/user-reducer.js +0 -30
- package/src/reducers/vertices-reducer.js +0 -34
- package/src/reducers/viewer2d-reducer.js +0 -81
- package/src/reducers/viewer3d-reducer.js +0 -65
- package/src/shared-style.js +0 -72
- package/src/styles/export.js +0 -7
- package/src/styles/tabs.css +0 -40
- package/src/translator/en.js +0 -106
- package/src/translator/it.js +0 -80
- package/src/translator/ru.js +0 -80
- package/src/translator/translator.js +0 -81
- package/src/utils/browser.js +0 -36
- package/src/utils/email-validator.js +0 -5
- package/src/utils/export.js +0 -39
- package/src/utils/geometry.js +0 -2572
- package/src/utils/get-edges-of-subgraphs.js +0 -29
- package/src/utils/graph-cycles.js +0 -259
- package/src/utils/graph-inner-cycles.js +0 -49
- package/src/utils/graph.js +0 -147
- package/src/utils/helper.js +0 -431
- package/src/utils/history.js +0 -37
- package/src/utils/id-broker.js +0 -9
- package/src/utils/logger.js +0 -8
- package/src/utils/math.js +0 -51
- package/src/utils/molding.js +0 -973
- package/src/utils/name-generator.js +0 -5
- package/src/utils/objects-utils.js +0 -56
- package/src/utils/phone-validator.js +0 -4
- package/src/utils/process-black-list.js +0 -10
- package/src/utils/react-if.jsx +0 -20
- package/src/utils/snap-scene.js +0 -102
- package/src/utils/snap.js +0 -184
- package/src/utils/threeCSG.es6.js +0 -578
- package/src/version.js +0 -1
package/src/utils/geometry.js
DELETED
|
@@ -1,2572 +0,0 @@
|
|
|
1
|
-
/** @description Determines the distance between two points
|
|
2
|
-
* @param {number} x0 Vertex 0 x
|
|
3
|
-
* @param {number} y0 Vertex 0 y
|
|
4
|
-
* @param {number} x1 Vertex 1 x
|
|
5
|
-
* @param {number} y1 Vertex 1 y
|
|
6
|
-
* @return {number}
|
|
7
|
-
*/
|
|
8
|
-
import { toFixedFloat, fAbs } from './math.js';
|
|
9
|
-
import {
|
|
10
|
-
BASE_CABINET_LAYOUTPOS,
|
|
11
|
-
EPSILON,
|
|
12
|
-
LINE_THICKNESS,
|
|
13
|
-
MEPSILON,
|
|
14
|
-
OVERLAP_INCLUDED,
|
|
15
|
-
OVERLAP_LINK,
|
|
16
|
-
OVERLAP_NONE,
|
|
17
|
-
OVERLAP_SAME,
|
|
18
|
-
OVERLAP_SOME,
|
|
19
|
-
WALL_CABINET_LAYOUTPOS,
|
|
20
|
-
UNIT_ANGLE,
|
|
21
|
-
MIN_ANGLE_DISALLOW_DRAW_WALL
|
|
22
|
-
} from '../constants';
|
|
23
|
-
import convert from 'convert-units';
|
|
24
|
-
import * as Three from 'three';
|
|
25
|
-
import { returnReplaceableDeepSearchType } from '../components/viewer2d/utils.js';
|
|
26
|
-
import { isEmpty } from './helper.js';
|
|
27
|
-
import { MathUtils } from './export.js';
|
|
28
|
-
|
|
29
|
-
export function compareVertices(v0, v1) {
|
|
30
|
-
return v0.x === v1.x ? v0.y - v1.y : v0.x - v1.x;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function minVertex(v0, v1) {
|
|
34
|
-
return compareVertices(v0, v1) > 0 ? v1 : v0;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function maxVertex(v0, v1) {
|
|
38
|
-
return compareVertices(v0, v1) > 0 ? v0 : v1;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function orderVertices(vertices) {
|
|
42
|
-
return vertices.sort(compareVertices);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export function pointsDistance(x0, y0, x1, y1) {
|
|
46
|
-
let diff_x = x0 - x1;
|
|
47
|
-
let diff_y = y0 - y1;
|
|
48
|
-
|
|
49
|
-
return Math.sqrt(diff_x * diff_x + diff_y * diff_y);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export function verticesDistance(v1, v2) {
|
|
53
|
-
let { x: x0, y: y0 } = v1;
|
|
54
|
-
let { x: x1, y: y1 } = v2;
|
|
55
|
-
|
|
56
|
-
return pointsDistance(x0, y0, x1, y1);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function horizontalLine(y) {
|
|
60
|
-
return { a: 0, b: 1, c: -y };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export const almostEqual = (x, y) => Math.abs(x - y) < EPSILON;
|
|
64
|
-
|
|
65
|
-
export function verticalLine(x) {
|
|
66
|
-
return { a: 1, b: 0, c: -x };
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function upcrossLine(x, y) {
|
|
70
|
-
return { a: 1, b: 1, c: -x - y };
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function downcrossLine(x, y) {
|
|
74
|
-
return { a: 1, b: -1, c: -x + y };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function linePassingThroughTwoPoints(x1, y1, x2, y2) {
|
|
78
|
-
if (x1 === x2 && y1 == y2) throw new Error('Geometry error');
|
|
79
|
-
//if (x1 === x2) return verticalLine(x1);
|
|
80
|
-
//if (y1 === y2) return horizontalLine(y1);
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
a: y1 - y2,
|
|
84
|
-
b: x2 - x1,
|
|
85
|
-
c: y2 * x1 - x2 * y1
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function getNormaline(x1, y1, x2, y2) {
|
|
90
|
-
let lineFunction = linePassingThroughTwoPoints(x1, y1, x2, y2);
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
x:
|
|
94
|
-
lineFunction.a /
|
|
95
|
-
Math.sqrt(
|
|
96
|
-
lineFunction.a * lineFunction.a + lineFunction.b * lineFunction.b
|
|
97
|
-
),
|
|
98
|
-
y:
|
|
99
|
-
lineFunction.b /
|
|
100
|
-
Math.sqrt(
|
|
101
|
-
lineFunction.a * lineFunction.a + lineFunction.b * lineFunction.b
|
|
102
|
-
)
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function distancePointFromLine(a, b, c, x, y) {
|
|
107
|
-
//https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
|
|
108
|
-
return fAbs(a * x + b * y + c) / Math.sqrt(a * a + b * b);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export function closestPointFromLine(a, b, c, x, y) {
|
|
112
|
-
//https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line
|
|
113
|
-
let denom = a * a + b * b;
|
|
114
|
-
return {
|
|
115
|
-
x: (b * (b * x - a * y) - a * c) / denom,
|
|
116
|
-
y: (a * -b * x + a * y - b * c) / denom
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** @description Get point of intersection between two lines using ax+by+c line's equation
|
|
121
|
-
* @param {number} a x coefficent of first line
|
|
122
|
-
* @param {number} b y coefficent of first line
|
|
123
|
-
* @param {number} c costant of first line
|
|
124
|
-
* @param {number} j x coefficent of second line
|
|
125
|
-
* @param {number} k y coefficent of second line
|
|
126
|
-
* @param {number} l costant of second line
|
|
127
|
-
* @return {object} {x,y} point's coordinates
|
|
128
|
-
*/
|
|
129
|
-
export function twoLinesIntersection(a, b, c, j, k, l) {
|
|
130
|
-
let angularCoefficientsDiff = b * j - a * k;
|
|
131
|
-
|
|
132
|
-
if (angularCoefficientsDiff === 0) return undefined; //no intersection
|
|
133
|
-
|
|
134
|
-
let y = (a * l - c * j) / angularCoefficientsDiff;
|
|
135
|
-
let x = (c * k - b * l) / angularCoefficientsDiff;
|
|
136
|
-
return { x, y };
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export function twoLineSegmentsIntersection(p1, p2, p3, p4) {
|
|
140
|
-
//https://github.com/psalaets/line-intersect/blob/master/lib/check-intersection.js
|
|
141
|
-
|
|
142
|
-
let { x: x1, y: y1 } = p1;
|
|
143
|
-
let { x: x2, y: y2 } = p2;
|
|
144
|
-
let { x: x3, y: y3 } = p3;
|
|
145
|
-
let { x: x4, y: y4 } = p4;
|
|
146
|
-
|
|
147
|
-
let denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
|
|
148
|
-
let numA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
|
|
149
|
-
let numB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
|
|
150
|
-
|
|
151
|
-
if (fAbs(denom) <= EPSILON) {
|
|
152
|
-
if (fAbs(numA) <= EPSILON && fAbs(numB) <= EPSILON) {
|
|
153
|
-
let comparator = (pa, pb) => (pa.x === pb.x ? pa.y - pb.y : pa.x - pb.x);
|
|
154
|
-
let line0 = [p1, p2].sort(comparator);
|
|
155
|
-
let line1 = [p3.toJS(), p4.toJS()].sort(comparator);
|
|
156
|
-
|
|
157
|
-
let [lineSX, lineDX] = [line0, line1].sort((lineA, lineB) =>
|
|
158
|
-
comparator(lineA[0], lineB[0])
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
if (lineSX[1].x === lineDX[0].x) {
|
|
162
|
-
return { type: lineDX[0].y <= lineSX[1].y ? 'colinear' : 'none' };
|
|
163
|
-
} else {
|
|
164
|
-
return { type: lineDX[0].x <= lineSX[1].x ? 'colinear' : 'none' };
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return { type: 'parallel' };
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
let uA = numA / denom;
|
|
171
|
-
let uB = numB / denom;
|
|
172
|
-
|
|
173
|
-
if (
|
|
174
|
-
uA >= 0 - EPSILON &&
|
|
175
|
-
uA <= 1 + EPSILON &&
|
|
176
|
-
uB >= 0 - EPSILON &&
|
|
177
|
-
uB <= 1 + EPSILON
|
|
178
|
-
) {
|
|
179
|
-
let point = {
|
|
180
|
-
x: x1 + uA * (x2 - x1),
|
|
181
|
-
y: y1 + uA * (y2 - y1)
|
|
182
|
-
};
|
|
183
|
-
return { type: 'intersecting', point };
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return { type: 'none' };
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function distancePointFromLineSegment(v1, v2, xp, yp) {
|
|
190
|
-
//http://stackoverflow.com/a/6853926/1398836
|
|
191
|
-
let { x: x1, y: y1 } = v1;
|
|
192
|
-
let { x: x2, y: y2 } = v2;
|
|
193
|
-
|
|
194
|
-
let A = xp - x1;
|
|
195
|
-
let B = yp - y1;
|
|
196
|
-
let C = x2 - x1;
|
|
197
|
-
let D = y2 - y1;
|
|
198
|
-
|
|
199
|
-
let dot = A * C + B * D;
|
|
200
|
-
let len_sq = C * C + D * D;
|
|
201
|
-
let param = -1;
|
|
202
|
-
if (len_sq != 0)
|
|
203
|
-
//in case of 0 length line
|
|
204
|
-
param = dot / len_sq;
|
|
205
|
-
|
|
206
|
-
let xx, yy;
|
|
207
|
-
|
|
208
|
-
if (param < 0) {
|
|
209
|
-
xx = x1;
|
|
210
|
-
yy = y1;
|
|
211
|
-
} else if (param > 1) {
|
|
212
|
-
xx = x2;
|
|
213
|
-
yy = y2;
|
|
214
|
-
} else {
|
|
215
|
-
xx = x1 + param * C;
|
|
216
|
-
yy = y1 + param * D;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
let dx = xp - xx;
|
|
220
|
-
let dy = yp - yy;
|
|
221
|
-
return Math.sqrt(dx * dx + dy * dy);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
*
|
|
226
|
-
* @param x1 {number} x for first vertex of the segment
|
|
227
|
-
* @param y1 {number} y for first vertex of the segment
|
|
228
|
-
* @param x2 {number} x for second vertex of the segment
|
|
229
|
-
* @param y2 {number} y for second vertex of the segment
|
|
230
|
-
* @param xp {number} x for point we want to verify
|
|
231
|
-
* @param yp {number} y for point we want to verify
|
|
232
|
-
* @param maxDistance {number} the epsilon value used for comparisons
|
|
233
|
-
* @returns {boolean} true if the point lies on the line segment false otherwise
|
|
234
|
-
*/
|
|
235
|
-
export function isPointOnLineSegment(
|
|
236
|
-
x1,
|
|
237
|
-
y1,
|
|
238
|
-
x2,
|
|
239
|
-
y2,
|
|
240
|
-
xp,
|
|
241
|
-
yp,
|
|
242
|
-
maxDistance = EPSILON
|
|
243
|
-
) {
|
|
244
|
-
return (
|
|
245
|
-
distancePointFromLineSegment({ x: x1, y: y1 }, { x: x2, y: y2 }, xp, yp) <=
|
|
246
|
-
maxDistance
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export function closestPointFromLineSegment(x1, y1, x2, y2, xp, yp) {
|
|
251
|
-
if (x1 === x2) return { x: x1, y: yp };
|
|
252
|
-
if (y1 === y2) return { x: xp, y: y1 };
|
|
253
|
-
|
|
254
|
-
let m = (y2 - y1) / (x2 - x1);
|
|
255
|
-
let q = y1 - m * x1;
|
|
256
|
-
|
|
257
|
-
let mi = -1 / m;
|
|
258
|
-
let qi = yp - mi * xp;
|
|
259
|
-
|
|
260
|
-
let x = (qi - q) / (m - mi);
|
|
261
|
-
let y = m * x + q;
|
|
262
|
-
|
|
263
|
-
return { x, y };
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export function pointPositionOnLineSegment(x1, y1, x2, y2, xp, yp) {
|
|
267
|
-
let length = pointsDistance(x1, y1, x2, y2);
|
|
268
|
-
let distance = pointsDistance(x1, y1, xp, yp);
|
|
269
|
-
|
|
270
|
-
let offset = distance / length;
|
|
271
|
-
/*
|
|
272
|
-
if (x1 > x2) offset = 1 - offset;
|
|
273
|
-
if (y1 > y2) offset = 1 - offset;
|
|
274
|
-
*/
|
|
275
|
-
return offset;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export function mapRange(value, low1, high1, low2, high2) {
|
|
279
|
-
return low2 + ((high2 - low2) * (value - low1)) / (high1 - low1);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
export function angleBetweenTwoPointsAndOrigin(x1, y1, x2, y2) {
|
|
283
|
-
return (-Math.atan2(y1 - y2, x2 - x1) * 180) / Math.PI;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
export function angleBetweenTwoPoints(x1, y1, x2, y2) {
|
|
287
|
-
return Math.atan2(y2 - y1, x2 - x1);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export function angleBetweenTwoLines(line, drawingLine, vertices) {
|
|
291
|
-
const points = [];
|
|
292
|
-
|
|
293
|
-
// safety guards
|
|
294
|
-
const lv = Array.isArray(line?.vertices) ? line.vertices : [];
|
|
295
|
-
const dv = Array.isArray(drawingLine?.vertices) ? drawingLine.vertices : [];
|
|
296
|
-
|
|
297
|
-
// 1) push common vertices (in order of line.vertices)
|
|
298
|
-
for (const vt of lv) {
|
|
299
|
-
if (dv.includes(vt) && !points.includes(vt)) points.push(vt);
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
// 2) push remaining vertices from line.vertices
|
|
303
|
-
for (const vt of lv) {
|
|
304
|
-
if (!points.includes(vt)) points.push(vt);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
// 3) push remaining vertices from drawingLine.vertices
|
|
308
|
-
for (const vt of dv) {
|
|
309
|
-
if (!points.includes(vt)) points.push(vt);
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
// If no points at all, nothing to compute — return 0 (safe fallback)
|
|
313
|
-
if (points.length === 0) return 0;
|
|
314
|
-
|
|
315
|
-
// Ensure we have at least 3 entries (same behaviour as original)
|
|
316
|
-
while (points.length < 3) points.push(points[points.length - 1]);
|
|
317
|
-
|
|
318
|
-
const [c, p1, p2] = points.slice(0, 3).map(idx => {
|
|
319
|
-
const v = vertices?.[idx];
|
|
320
|
-
return v ? new Three.Vector2(v.x, v.y) : new Three.Vector2(0, 0);
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
const vec1 = p1.clone().sub(c).normalize();
|
|
324
|
-
const vec2 = p2.clone().sub(c).normalize();
|
|
325
|
-
|
|
326
|
-
return Math.floor(
|
|
327
|
-
(vec1.angle() * 180) / Math.PI - (vec2.angle() * 180) / Math.PI + 0.5
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
export const getRelatedLines = (
|
|
332
|
-
tlines,
|
|
333
|
-
drawingLine,
|
|
334
|
-
vertices,
|
|
335
|
-
lines,
|
|
336
|
-
exceptLineId = null
|
|
337
|
-
) => {
|
|
338
|
-
if (!drawingLine?.vertices || !Array.isArray(drawingLine.vertices)) return;
|
|
339
|
-
|
|
340
|
-
const seen = new Set();
|
|
341
|
-
|
|
342
|
-
for (const vIdx of drawingLine.vertices) {
|
|
343
|
-
const vertex = vertices?.[vIdx];
|
|
344
|
-
if (!vertex?.lines) continue;
|
|
345
|
-
|
|
346
|
-
for (const lineId of vertex.lines) {
|
|
347
|
-
if (
|
|
348
|
-
lineId !== drawingLine.id &&
|
|
349
|
-
lineId !== exceptLineId &&
|
|
350
|
-
!isEmpty(lines?.[lineId]) &&
|
|
351
|
-
!seen.has(lineId)
|
|
352
|
-
) {
|
|
353
|
-
seen.add(lineId);
|
|
354
|
-
tlines.push(lines[lineId]);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
export function snapAngleByUnit(
|
|
361
|
-
lineAngle,
|
|
362
|
-
vertices,
|
|
363
|
-
drawingLine,
|
|
364
|
-
x,
|
|
365
|
-
y,
|
|
366
|
-
dragVertexId
|
|
367
|
-
) {
|
|
368
|
-
let tx, ty;
|
|
369
|
-
let absAngle = Math.abs(lineAngle);
|
|
370
|
-
// angle snapping as a value of UNIT_ANGLE
|
|
371
|
-
let rest = absAngle % UNIT_ANGLE;
|
|
372
|
-
let missAngle = UNIT_ANGLE - rest;
|
|
373
|
-
// the origin point of rotation(snapping)
|
|
374
|
-
let originVerId = drawingLine.vertices.findIndex(
|
|
375
|
-
vertice => vertice !== dragVertexId
|
|
376
|
-
);
|
|
377
|
-
originVerId =
|
|
378
|
-
originVerId < 0
|
|
379
|
-
? drawingLine.vertices[0]
|
|
380
|
-
: drawingLine.vertices[originVerId];
|
|
381
|
-
|
|
382
|
-
let ox = vertices[originVerId].x;
|
|
383
|
-
let oy = vertices[originVerId].y;
|
|
384
|
-
// check whether the line is snapped to before point.
|
|
385
|
-
if (rest <= UNIT_ANGLE / 2) {
|
|
386
|
-
// determine the direction of rotation.
|
|
387
|
-
rest = lineAngle > 0 ? rest : -rest;
|
|
388
|
-
// rotate the current point to last point around the first point of drawing line.
|
|
389
|
-
tx = rotatePointAroundPoint(x, y, ox, oy, rest).x;
|
|
390
|
-
ty = rotatePointAroundPoint(x, y, ox, oy, rest).y;
|
|
391
|
-
}
|
|
392
|
-
// check whether the line is snapped to next new point.
|
|
393
|
-
else if (rest > UNIT_ANGLE / 2) {
|
|
394
|
-
// determine the direction of rotation.
|
|
395
|
-
missAngle = lineAngle > 0 ? -missAngle : missAngle;
|
|
396
|
-
// rotate the current point to last point around the first point of drawing line.
|
|
397
|
-
tx = rotatePointAroundPoint(x, y, ox, oy, missAngle).x;
|
|
398
|
-
ty = rotatePointAroundPoint(x, y, ox, oy, missAngle).y;
|
|
399
|
-
}
|
|
400
|
-
let resPoint = {
|
|
401
|
-
x: tx,
|
|
402
|
-
y: ty
|
|
403
|
-
};
|
|
404
|
-
return resPoint;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
export function absAngleBetweenTwoPoints(x1, y1, x2, y2) {
|
|
408
|
-
return Math.atan2(y2 - y1, Math.abs(x2 - x1));
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
export function samePoints({ x: x1, y: y1 }, { x: x2, y: y2 }) {
|
|
412
|
-
return fAbs(x1 - x2) <= EPSILON && fAbs(y1 - y2) <= EPSILON;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
export function sameDistances(dis1, dis2) {
|
|
416
|
-
return fAbs(dis1 - dis2) <= EPSILON;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
export function sameMPoints({ x: x1, y: y1 }, { x: x2, y: y2 }) {
|
|
420
|
-
return fAbs(x1 - x2) <= MEPSILON && fAbs(y1 - y2) <= MEPSILON;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
export function sameMDistances(dis1, dis2) {
|
|
424
|
-
return fAbs(dis1 - dis2) <= MEPSILON;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
export function isPointInRect(rect, point) {
|
|
428
|
-
let result = true;
|
|
429
|
-
for (let i = 0; i < rect.length; i++) {
|
|
430
|
-
let pos1 = rect[i];
|
|
431
|
-
let pos2 = rect[(i + 1) % rect.length];
|
|
432
|
-
|
|
433
|
-
if (
|
|
434
|
-
isPointOnLineSegment(pos1.x, pos1.y, pos2.x, pos2.y, point.x, point.y)
|
|
435
|
-
) {
|
|
436
|
-
result = false;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
return result;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
/** @description Extend line based on coordinates and new line length
|
|
443
|
-
* @param {number} x1 Vertex 1 x
|
|
444
|
-
* @param {number} y1 Vertex 1 y
|
|
445
|
-
* @param {number} x2 Vertex 2 x
|
|
446
|
-
* @param {number} y2 Vertex 2 y
|
|
447
|
-
* @param {number} newDistance New line length
|
|
448
|
-
* @return {object}
|
|
449
|
-
*/
|
|
450
|
-
export function extendLine(x1, y1, x2, y2, newDistance, precision = 6) {
|
|
451
|
-
let rad = angleBetweenTwoPoints(x1, y1, x2, y2);
|
|
452
|
-
|
|
453
|
-
return {
|
|
454
|
-
x: toFixedFloat(x1 + Math.cos(rad) * newDistance, precision),
|
|
455
|
-
y: toFixedFloat(y1 + Math.sin(rad) * newDistance, precision)
|
|
456
|
-
};
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
export function roundVertex(vertex, precision = 6) {
|
|
460
|
-
vertex.set('x', toFixedFloat(vertex.get('x'), precision));
|
|
461
|
-
vertex.set('y', toFixedFloat(vertex.get('y'), precision));
|
|
462
|
-
|
|
463
|
-
return vertex;
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
//https://github.com/MartyWallace/PolyK
|
|
467
|
-
export function ContainsPoint(polygon, pointX, pointY) {
|
|
468
|
-
let n = polygon.length >> 1;
|
|
469
|
-
let ax, lup;
|
|
470
|
-
let ay = polygon[2 * n - 3] - pointY;
|
|
471
|
-
let bx = polygon[2 * n - 2] - pointX;
|
|
472
|
-
let by = polygon[2 * n - 1] - pointY;
|
|
473
|
-
|
|
474
|
-
if (bx === 0 && by === 0) return false; // point on edge
|
|
475
|
-
|
|
476
|
-
// let lup = by > ay;
|
|
477
|
-
for (let ii = 0; ii < n; ii++) {
|
|
478
|
-
ax = bx;
|
|
479
|
-
ay = by;
|
|
480
|
-
bx = polygon[2 * ii] - pointX;
|
|
481
|
-
by = polygon[2 * ii + 1] - pointY;
|
|
482
|
-
if (bx === 0 && by === 0) return false; // point on edge
|
|
483
|
-
if (ay === by) continue;
|
|
484
|
-
lup = by > ay;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
let depth = 0;
|
|
488
|
-
for (let i = 0; i < n; i++) {
|
|
489
|
-
ax = bx;
|
|
490
|
-
ay = by;
|
|
491
|
-
bx = polygon[2 * i] - pointX;
|
|
492
|
-
by = polygon[2 * i + 1] - pointY;
|
|
493
|
-
if (ay < 0 && by < 0) continue; // both 'up' or both 'down'
|
|
494
|
-
if (ay > 0 && by > 0) continue; // both 'up' or both 'down'
|
|
495
|
-
if (ax < 0 && bx < 0) continue; // both points on the left
|
|
496
|
-
|
|
497
|
-
if (ay === by && Math.min(ax, bx) < 0) return true;
|
|
498
|
-
if (ay === by) continue;
|
|
499
|
-
|
|
500
|
-
let lx = ax + ((bx - ax) * -ay) / (by - ay);
|
|
501
|
-
if (lx === 0) return false; // point on edge
|
|
502
|
-
if (lx > 0) depth++;
|
|
503
|
-
if (ay === 0 && lup && by > ay) depth--; // hit vertex, both up
|
|
504
|
-
if (ay === 0 && !lup && by < ay) depth--; // hit vertex, both down
|
|
505
|
-
lup = by > ay;
|
|
506
|
-
}
|
|
507
|
-
return (depth & 1) === 1;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
export function cosWithThreshold(alpha, threshold) {
|
|
511
|
-
let cos = Math.cos(alpha);
|
|
512
|
-
return cos < threshold ? 0 : cos;
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
export function sinWithThreshold(alpha, threshold) {
|
|
516
|
-
let sin = Math.sin(alpha);
|
|
517
|
-
return sin < threshold ? 0 : sin;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
export function midPoint(x1, y1, x2, y2) {
|
|
521
|
-
return { x: (x1 + x2) / 2, y: (y1 + y2) / 2 };
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
export function verticesMidPoint(verticesArray) {
|
|
525
|
-
let res = verticesArray.reduce(
|
|
526
|
-
(incr, vertex) => {
|
|
527
|
-
return { x: incr.x + vertex.x, y: incr.y + vertex.y };
|
|
528
|
-
},
|
|
529
|
-
{ x: 0, y: 0 }
|
|
530
|
-
);
|
|
531
|
-
return { x: res.x / verticesArray.length, y: res.y / verticesArray.length };
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
export function rotatePointAroundPoint(px, py, ox, oy, theta) {
|
|
535
|
-
let thetaRad = (theta * Math.PI) / 180;
|
|
536
|
-
|
|
537
|
-
let cos = Math.cos(thetaRad);
|
|
538
|
-
let sin = Math.sin(thetaRad);
|
|
539
|
-
|
|
540
|
-
let deltaX = px - ox;
|
|
541
|
-
let deltaY = py - oy;
|
|
542
|
-
|
|
543
|
-
return {
|
|
544
|
-
x: cos * deltaX - sin * deltaY + ox,
|
|
545
|
-
y: sin * deltaX + cos * deltaY + oy
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
// point: x,y
|
|
550
|
-
// itemrectInfo: pos(x,y),rotRad,size,layoutpos,is_corner
|
|
551
|
-
// calcRect: rect(point[4]),pos(x,y),rotRad,size,layoutpos,is_corner
|
|
552
|
-
|
|
553
|
-
function point(x, y) {
|
|
554
|
-
return { x, y };
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function itemrectInfo(x, y, rotRad, size, layoutpos, is_corner) {
|
|
558
|
-
return { pos: { x, y }, rotRad, size, layoutpos, is_corner };
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
export function getCalcRectFromItem(item) {
|
|
562
|
-
let itemInfo;
|
|
563
|
-
if (item === undefined) itemInfo = [];
|
|
564
|
-
else itemInfo = item.item;
|
|
565
|
-
let x = item.pos.x;
|
|
566
|
-
let y = item.pos.y;
|
|
567
|
-
let rotRad = item.rotRad;
|
|
568
|
-
let w = item.size && item.size.width / 2;
|
|
569
|
-
let h = item.size && item.size.height / 2;
|
|
570
|
-
let mx = x - w * Math.cos(rotRad);
|
|
571
|
-
let my = y - w * Math.sin(rotRad);
|
|
572
|
-
let x0 = mx + h * Math.sin(rotRad);
|
|
573
|
-
let y0 = my - h * Math.cos(rotRad);
|
|
574
|
-
let x3 = mx * 2 - x0;
|
|
575
|
-
let y3 = my * 2 - y0;
|
|
576
|
-
let x1 = x * 2 - x3;
|
|
577
|
-
let y1 = y * 2 - y3;
|
|
578
|
-
let x2 = x * 2 - x0;
|
|
579
|
-
let y2 = y * 2 - y0;
|
|
580
|
-
|
|
581
|
-
return {
|
|
582
|
-
rect: [point(x0, y0), point(x1, y1), point(x2, y2), point(x3, y3)],
|
|
583
|
-
pos: point(x, y),
|
|
584
|
-
rotRad,
|
|
585
|
-
size: item.size,
|
|
586
|
-
layoutpos: item.layoutpos,
|
|
587
|
-
is_corner: item.is_corner,
|
|
588
|
-
itemInfo: itemInfo
|
|
589
|
-
};
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
export function getCalcRectFromItem3D(item) {
|
|
593
|
-
let itemInfo;
|
|
594
|
-
if (item === undefined) itemInfo = [];
|
|
595
|
-
else itemInfo = item.item;
|
|
596
|
-
let x = item.pos.x;
|
|
597
|
-
let y = item.pos.y;
|
|
598
|
-
let rotRad = item.rotRad;
|
|
599
|
-
let w = item.size.width / 2;
|
|
600
|
-
let h = item.size.depth / 2;
|
|
601
|
-
let mx = x - w * Math.cos(rotRad);
|
|
602
|
-
let my = y - w * Math.sin(rotRad);
|
|
603
|
-
let x0 = mx + h * Math.sin(rotRad);
|
|
604
|
-
let y0 = my - h * Math.cos(rotRad);
|
|
605
|
-
let x3 = mx * 2 - x0;
|
|
606
|
-
let y3 = my * 2 - y0;
|
|
607
|
-
let x1 = x * 2 - x3;
|
|
608
|
-
let y1 = y * 2 - y3;
|
|
609
|
-
let x2 = x * 2 - x0;
|
|
610
|
-
let y2 = y * 2 - y0;
|
|
611
|
-
|
|
612
|
-
return {
|
|
613
|
-
rect: [point(x0, y0), point(x1, y1), point(x2, y2), point(x3, y3)],
|
|
614
|
-
pos: point(x, y),
|
|
615
|
-
rotRad,
|
|
616
|
-
size: item.size,
|
|
617
|
-
layoutpos: item.layoutpos,
|
|
618
|
-
is_corner: item.is_corner,
|
|
619
|
-
itemInfo: itemInfo
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
export function getAllItems(scene, catalog, allLineRects) {
|
|
624
|
-
let layerID = scene.selectedLayer;
|
|
625
|
-
let layer = scene.layers.get(layerID);
|
|
626
|
-
|
|
627
|
-
let curiteminfo;
|
|
628
|
-
let iteminfo = [];
|
|
629
|
-
let otherItems = [];
|
|
630
|
-
|
|
631
|
-
let selectedItem;
|
|
632
|
-
let currentItem;
|
|
633
|
-
|
|
634
|
-
if (layer.selected.items.size > 0) {
|
|
635
|
-
selectedItem = layer.getIn(['items', layer.selected.items.get(0)]);
|
|
636
|
-
let catid = selectedItem.type;
|
|
637
|
-
let cat = catalog.elements[catid];
|
|
638
|
-
if (!cat) cat = catalog.elements[returnReplaceableDeepSearchType(catid)];
|
|
639
|
-
currentItem = {
|
|
640
|
-
selectedItem,
|
|
641
|
-
cat
|
|
642
|
-
};
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
layer.items.forEach(item => {
|
|
646
|
-
let val = {
|
|
647
|
-
pos: { x: item.x, y: item.y },
|
|
648
|
-
rotRad: (item.rotation / 180) * Math.PI
|
|
649
|
-
};
|
|
650
|
-
let catid = item.type;
|
|
651
|
-
let cat = catalog.elements[catid];
|
|
652
|
-
|
|
653
|
-
if (!cat) {
|
|
654
|
-
cat = catalog.elements[returnReplaceableDeepSearchType(catid)];
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
let sizeinfo = [];
|
|
658
|
-
let width, height, depth;
|
|
659
|
-
|
|
660
|
-
sizeinfo = {
|
|
661
|
-
width: item.properties.get('width').get('_length'),
|
|
662
|
-
height: item.properties.get('height').get('_length'),
|
|
663
|
-
depth: item.properties.get('depth').get('_length'),
|
|
664
|
-
widthUnit: item.properties.get('width').get('_unit'),
|
|
665
|
-
heightUnit: item.properties.get('height').get('_unit'),
|
|
666
|
-
depthUnit: item.properties.get('depth').get('_unit')
|
|
667
|
-
};
|
|
668
|
-
sizeinfo = {
|
|
669
|
-
...sizeinfo,
|
|
670
|
-
layoutpos: cat && cat.info.layoutpos,
|
|
671
|
-
is_corner: cat && cat.info.is_corner
|
|
672
|
-
};
|
|
673
|
-
|
|
674
|
-
width = convert(sizeinfo.width).from(sizeinfo.widthUnit).to(scene.unit);
|
|
675
|
-
height = convert(sizeinfo.depth).from(sizeinfo.depthUnit).to(scene.unit);
|
|
676
|
-
depth = convert(sizeinfo.height).from(sizeinfo.heightUnit).to(scene.unit);
|
|
677
|
-
|
|
678
|
-
val.size = { width, height, depth };
|
|
679
|
-
val.layoutpos = sizeinfo.layoutpos;
|
|
680
|
-
val.is_corner = sizeinfo.is_corner;
|
|
681
|
-
val.doorStyle = item.doorStyle;
|
|
682
|
-
val.item = item;
|
|
683
|
-
|
|
684
|
-
let otherItem = {
|
|
685
|
-
item,
|
|
686
|
-
cat
|
|
687
|
-
};
|
|
688
|
-
|
|
689
|
-
if (!needSnap(currentItem, otherItem)) {
|
|
690
|
-
return;
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
if (item.selected) {
|
|
694
|
-
curiteminfo = getCalcRectFromItem(val);
|
|
695
|
-
} else {
|
|
696
|
-
let calcrect = getCalcRectFromItem(val);
|
|
697
|
-
calcrect.isSnappedLine = isSnappedLine(calcrect, allLineRects);
|
|
698
|
-
iteminfo.push(calcrect);
|
|
699
|
-
otherItems.push(otherItem);
|
|
700
|
-
}
|
|
701
|
-
});
|
|
702
|
-
return { cur: curiteminfo, others: iteminfo, currentItem, otherItems };
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
export function getAllItemSpecified(scene, catalog, filter) {
|
|
706
|
-
const layerID = scene?.selectedLayer;
|
|
707
|
-
const layer = scene?.layers?.get?.(layerID);
|
|
708
|
-
if (!layer || !layer.items) return { cur: null, others: [] };
|
|
709
|
-
|
|
710
|
-
let curiteminfo;
|
|
711
|
-
const iteminfo = [];
|
|
712
|
-
|
|
713
|
-
layer.items.forEach(item => {
|
|
714
|
-
if (!item) return;
|
|
715
|
-
|
|
716
|
-
const val = {
|
|
717
|
-
pos: { x: item.x, y: item.y },
|
|
718
|
-
rotRad: (item.rotation / 180) * Math.PI
|
|
719
|
-
};
|
|
720
|
-
|
|
721
|
-
const cat = item.type ? findCatalogElement(catalog, item.type) : null;
|
|
722
|
-
const info = cat?.info;
|
|
723
|
-
|
|
724
|
-
const props = item.properties;
|
|
725
|
-
const getSize = key => {
|
|
726
|
-
const length = props?.getIn?.([key, '_length']);
|
|
727
|
-
return length != null ? convert(length).from('in').to(scene.unit) : 0;
|
|
728
|
-
};
|
|
729
|
-
|
|
730
|
-
val.size = {
|
|
731
|
-
width: getSize('width'),
|
|
732
|
-
height: getSize('height'),
|
|
733
|
-
depth: getSize('depth')
|
|
734
|
-
};
|
|
735
|
-
|
|
736
|
-
val.item = item;
|
|
737
|
-
|
|
738
|
-
if (info) {
|
|
739
|
-
val.layoutpos = info.layoutpos;
|
|
740
|
-
val.is_corner = info.is_corner;
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
// Filter check
|
|
744
|
-
if (Array.isArray(filter)) {
|
|
745
|
-
if (info && !filter.includes(info.layoutpos)) return;
|
|
746
|
-
} else if (
|
|
747
|
-
info &&
|
|
748
|
-
(info.layoutpos !== filter ||
|
|
749
|
-
(cat?.type === 'appliance' &&
|
|
750
|
-
['Cook Top', 'Microwave'].includes(cat?.obj?.category)))
|
|
751
|
-
) {
|
|
752
|
-
return;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
// Current vs others
|
|
756
|
-
const rect = getCalcRectFromItem3D(val);
|
|
757
|
-
if (item.selected) {
|
|
758
|
-
curiteminfo = rect;
|
|
759
|
-
} else {
|
|
760
|
-
iteminfo.push(rect);
|
|
761
|
-
}
|
|
762
|
-
});
|
|
763
|
-
|
|
764
|
-
return { cur: curiteminfo, others: iteminfo };
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
export function findCatalogElement(catalog, elementName) {
|
|
768
|
-
if (!elementName || !catalog) return null;
|
|
769
|
-
|
|
770
|
-
const variants = [elementName, elementName.toLowerCase()];
|
|
771
|
-
const deepVariants = variants
|
|
772
|
-
.map(v => returnReplaceableDeepSearchType(v))
|
|
773
|
-
.filter(Boolean);
|
|
774
|
-
|
|
775
|
-
const allCandidates = [...variants, ...deepVariants];
|
|
776
|
-
|
|
777
|
-
const getElement = catid => {
|
|
778
|
-
if (!catid) return null;
|
|
779
|
-
|
|
780
|
-
// Immutable.js Map
|
|
781
|
-
if (typeof catalog.getIn === 'function') {
|
|
782
|
-
return catalog.getIn(['elements', catid]);
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
// Plain JS object
|
|
786
|
-
if (catalog.elements && catalog.elements[catid]) {
|
|
787
|
-
return catalog.elements[catid];
|
|
788
|
-
}
|
|
789
|
-
|
|
790
|
-
return null;
|
|
791
|
-
};
|
|
792
|
-
|
|
793
|
-
for (const name of allCandidates) {
|
|
794
|
-
const cat = getElement(name);
|
|
795
|
-
if (cat) return cat;
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
800
|
-
|
|
801
|
-
export function isSnappedLine(calcrect, allLineRects) {
|
|
802
|
-
if (allLineRects === undefined) return false;
|
|
803
|
-
|
|
804
|
-
let r2 = calcrect.rect[2];
|
|
805
|
-
let r3 = calcrect.rect[3];
|
|
806
|
-
let result = allLineRects.some(linerect => {
|
|
807
|
-
let l2 = linerect.rect[2];
|
|
808
|
-
let l3 = linerect.rect[3];
|
|
809
|
-
let delta =
|
|
810
|
-
verticesDistance(l2, r3) +
|
|
811
|
-
verticesDistance(r3, r2) +
|
|
812
|
-
verticesDistance(r2, l3) -
|
|
813
|
-
verticesDistance(l3, l2);
|
|
814
|
-
if (delta < EPSILON) {
|
|
815
|
-
return true;
|
|
816
|
-
} else {
|
|
817
|
-
l2 = linerect.rect[3];
|
|
818
|
-
l3 = linerect.rect[2];
|
|
819
|
-
delta =
|
|
820
|
-
verticesDistance(l2, r3) +
|
|
821
|
-
verticesDistance(r3, r2) +
|
|
822
|
-
verticesDistance(r2, l3) -
|
|
823
|
-
verticesDistance(l3, l2);
|
|
824
|
-
return delta < EPSILON;
|
|
825
|
-
}
|
|
826
|
-
});
|
|
827
|
-
return result;
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
export function isSnappedSideLine(calcrect, allLineRects) {
|
|
831
|
-
if (allLineRects === undefined) return 0;
|
|
832
|
-
let r2 = calcrect.rect[1];
|
|
833
|
-
let r3 = calcrect.rect[2];
|
|
834
|
-
let result = allLineRects.some(linerect => {
|
|
835
|
-
let l2 = linerect.rect[2];
|
|
836
|
-
let l3 = linerect.rect[3];
|
|
837
|
-
let delta =
|
|
838
|
-
verticesDistance(l2, r3) +
|
|
839
|
-
verticesDistance(r3, r2) +
|
|
840
|
-
verticesDistance(r2, l3) -
|
|
841
|
-
verticesDistance(l3, l2);
|
|
842
|
-
return delta < EPSILON;
|
|
843
|
-
});
|
|
844
|
-
return result;
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
/** Calculate candidate positions */
|
|
848
|
-
export function getAllItemSnap(allItemRects) {
|
|
849
|
-
let allItemSnap = [];
|
|
850
|
-
|
|
851
|
-
let cur = allItemRects.cur;
|
|
852
|
-
|
|
853
|
-
// For development
|
|
854
|
-
let { otherItems, currentItem } = allItemRects;
|
|
855
|
-
|
|
856
|
-
allItemRects.others.forEach((rect, index) => {
|
|
857
|
-
let cw = cur && cur.size.width / 2;
|
|
858
|
-
let ch = cur && cur.size.height / 2;
|
|
859
|
-
let cos = Math.cos(rect.rotRad);
|
|
860
|
-
let sin = Math.sin(rect.rotRad);
|
|
861
|
-
let ox0 = cw * cos - ch * sin; // (cw, ch) rot
|
|
862
|
-
let oy0 = cw * sin + ch * cos;
|
|
863
|
-
let ox1 = -cw * cos - ch * sin; // (-cw, ch) rot
|
|
864
|
-
let oy1 = -cw * sin + ch * cos;
|
|
865
|
-
let ox2 = ch * sin - cw * cos;
|
|
866
|
-
let oy2 = -ch * cos - cw * sin;
|
|
867
|
-
let ox3 = ch * sin + cw * cos;
|
|
868
|
-
let oy3 = -ch * cos + cw * sin;
|
|
869
|
-
let nrot = rect.rotRad + Math.PI;
|
|
870
|
-
if (nrot >= Math.PI) nrot -= Math.PI * 2;
|
|
871
|
-
let snap1 = itemrectInfo(
|
|
872
|
-
rect.rect[2].x + ox3,
|
|
873
|
-
rect.rect[2].y + oy3,
|
|
874
|
-
rect.rotRad,
|
|
875
|
-
cur && cur.size,
|
|
876
|
-
rect.layoutpos,
|
|
877
|
-
rect.is_corner
|
|
878
|
-
);
|
|
879
|
-
let snap2 = itemrectInfo(
|
|
880
|
-
rect.rect[3].x + ox2,
|
|
881
|
-
rect.rect[3].y + oy2,
|
|
882
|
-
rect.rotRad,
|
|
883
|
-
cur && cur.size,
|
|
884
|
-
rect.layoutpos,
|
|
885
|
-
rect.is_corner
|
|
886
|
-
);
|
|
887
|
-
let snap3 = itemrectInfo(
|
|
888
|
-
rect.rect[2].x + ox1,
|
|
889
|
-
rect.rect[2].y + oy1,
|
|
890
|
-
nrot,
|
|
891
|
-
cur && cur.size,
|
|
892
|
-
rect.layoutpos,
|
|
893
|
-
rect.is_corner
|
|
894
|
-
);
|
|
895
|
-
let snap4 = itemrectInfo(
|
|
896
|
-
rect.rect[3].x + ox0,
|
|
897
|
-
rect.rect[3].y + oy0,
|
|
898
|
-
nrot,
|
|
899
|
-
cur && cur.size,
|
|
900
|
-
rect.layoutpos,
|
|
901
|
-
rect.is_corner
|
|
902
|
-
);
|
|
903
|
-
|
|
904
|
-
const sizeinfo =
|
|
905
|
-
otherItems[index].cat && otherItems[index].cat.info.sizeinfo;
|
|
906
|
-
if (sizeinfo) {
|
|
907
|
-
const { leftBlindLength, rightBlindLength } = sizeinfo;
|
|
908
|
-
|
|
909
|
-
if (leftBlindLength > 0) {
|
|
910
|
-
let vx = leftBlindLength - ch;
|
|
911
|
-
let vy = cw;
|
|
912
|
-
let dx = vx * cos + vy * sin;
|
|
913
|
-
let dy = vx * sin - vy * cos;
|
|
914
|
-
let snap6 = itemrectInfo(
|
|
915
|
-
rect.rect[0].x + dx,
|
|
916
|
-
rect.rect[0].y + dy,
|
|
917
|
-
rect.rotRad + Math.PI / 2,
|
|
918
|
-
cur && cur.size,
|
|
919
|
-
rect.layoutpos,
|
|
920
|
-
rect.is_corner
|
|
921
|
-
);
|
|
922
|
-
allItemSnap.push(snap6);
|
|
923
|
-
}
|
|
924
|
-
if (rightBlindLength > 0) {
|
|
925
|
-
let vx = ch - rightBlindLength;
|
|
926
|
-
let vy = cw;
|
|
927
|
-
let dx = vx * cos + vy * sin;
|
|
928
|
-
let dy = vx * sin - vy * cos;
|
|
929
|
-
let snap7 = itemrectInfo(
|
|
930
|
-
rect.rect[1].x + dx,
|
|
931
|
-
rect.rect[1].y + dy,
|
|
932
|
-
rect.rotRad - Math.PI / 2,
|
|
933
|
-
cur && cur.size,
|
|
934
|
-
rect.layoutpos,
|
|
935
|
-
rect.is_corner
|
|
936
|
-
);
|
|
937
|
-
allItemSnap.push(snap7);
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
if (rect.isSnappedLine) {
|
|
942
|
-
snap1.isSnappedLine = true;
|
|
943
|
-
snap2.isSnappedLine = true;
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
if (rect.is_corner) {
|
|
947
|
-
let nrot = rect.rotRad + (Math.PI * 3) / 2;
|
|
948
|
-
if (nrot >= Math.PI) nrot -= Math.PI * 2;
|
|
949
|
-
let snap5 = itemrectInfo(
|
|
950
|
-
rect.rect[1].x - oy1,
|
|
951
|
-
rect.rect[1].y + ox1,
|
|
952
|
-
nrot,
|
|
953
|
-
cur && cur.size,
|
|
954
|
-
rect.layoutpos,
|
|
955
|
-
rect.is_corner
|
|
956
|
-
);
|
|
957
|
-
allItemSnap.push(snap2);
|
|
958
|
-
allItemSnap.push(snap5);
|
|
959
|
-
} else {
|
|
960
|
-
allItemSnap.push(snap1);
|
|
961
|
-
allItemSnap.push(snap2);
|
|
962
|
-
allItemSnap.push(snap3);
|
|
963
|
-
allItemSnap.push(snap4);
|
|
964
|
-
}
|
|
965
|
-
});
|
|
966
|
-
|
|
967
|
-
return allItemSnap;
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
export function getAllArea(layer) {
|
|
971
|
-
let allAreaLines = [];
|
|
972
|
-
let allLines = [];
|
|
973
|
-
let verticesArray = [];
|
|
974
|
-
let vertexID_to_verticesArrayIndex = {};
|
|
975
|
-
|
|
976
|
-
layer.vertices.forEach(vertex => {
|
|
977
|
-
let verticesCount = verticesArray.push([vertex.x, vertex.y]);
|
|
978
|
-
let latestVertexIndex = verticesCount - 1;
|
|
979
|
-
vertexID_to_verticesArrayIndex[vertex.id] = latestVertexIndex;
|
|
980
|
-
});
|
|
981
|
-
|
|
982
|
-
layer.areas.forEach(area => {
|
|
983
|
-
allAreaLines.push(area.vertices);
|
|
984
|
-
});
|
|
985
|
-
|
|
986
|
-
allAreaLines.forEach(area => {
|
|
987
|
-
let pt = [];
|
|
988
|
-
area.forEach(element => {
|
|
989
|
-
pt.push({
|
|
990
|
-
x: verticesArray[vertexID_to_verticesArrayIndex[element]][0],
|
|
991
|
-
y: verticesArray[vertexID_to_verticesArrayIndex[element]][1]
|
|
992
|
-
});
|
|
993
|
-
});
|
|
994
|
-
allLines.push(pt);
|
|
995
|
-
});
|
|
996
|
-
|
|
997
|
-
return allLines;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
/** Get all lines of the scene */
|
|
1001
|
-
export function getAllLines(layer) {
|
|
1002
|
-
let allAreaLines = getAllAreaLines(layer);
|
|
1003
|
-
|
|
1004
|
-
let allLines = [];
|
|
1005
|
-
//let allNonAreaLines = [];
|
|
1006
|
-
let thick = LINE_THICKNESS / 2;
|
|
1007
|
-
layer.lines.forEach(line => {
|
|
1008
|
-
let i = containLine(allAreaLines, line);
|
|
1009
|
-
// let thick = line.properties.getIn(['thickness', 'length']);
|
|
1010
|
-
if (i < 0) {
|
|
1011
|
-
let vertices = line.vertices.toJS();
|
|
1012
|
-
let tmp_vertices = {
|
|
1013
|
-
x1: layer.vertices.get(vertices[0]).x,
|
|
1014
|
-
y1: layer.vertices.get(vertices[0]).y,
|
|
1015
|
-
x2: layer.vertices.get(vertices[1]).x,
|
|
1016
|
-
y2: layer.vertices.get(vertices[1]).y
|
|
1017
|
-
};
|
|
1018
|
-
if (
|
|
1019
|
-
tmp_vertices.x1 == tmp_vertices.x2 &&
|
|
1020
|
-
tmp_vertices.y1 == tmp_vertices.y2
|
|
1021
|
-
)
|
|
1022
|
-
return;
|
|
1023
|
-
let addIdx = allLines.length;
|
|
1024
|
-
let flag = 0;
|
|
1025
|
-
allLines.forEach((element, idx) => {
|
|
1026
|
-
if (flag == 0) {
|
|
1027
|
-
let el = element[0];
|
|
1028
|
-
let tmp_el = {
|
|
1029
|
-
x1: layer.vertices.get(el[0]).x,
|
|
1030
|
-
y1: layer.vertices.get(el[0]).y,
|
|
1031
|
-
x2: layer.vertices.get(el[1]).x,
|
|
1032
|
-
y2: layer.vertices.get(el[1]).y
|
|
1033
|
-
};
|
|
1034
|
-
if (tmp_el.x1 == tmp_vertices.x1 && tmp_el.y1 == tmp_vertices.y1) {
|
|
1035
|
-
let tmp = vertices[0];
|
|
1036
|
-
vertices[0] = vertices[1];
|
|
1037
|
-
vertices[1] = tmp;
|
|
1038
|
-
addIdx = idx == 0 ? 0 : idx - 1;
|
|
1039
|
-
flag = 1;
|
|
1040
|
-
} else if (
|
|
1041
|
-
tmp_el.x2 == tmp_vertices.x1 &&
|
|
1042
|
-
tmp_el.y2 == tmp_vertices.y1
|
|
1043
|
-
) {
|
|
1044
|
-
addIdx = idx;
|
|
1045
|
-
flag = 1;
|
|
1046
|
-
} else if (
|
|
1047
|
-
tmp_el.x1 == tmp_vertices.x2 &&
|
|
1048
|
-
tmp_el.y1 == tmp_vertices.y2
|
|
1049
|
-
) {
|
|
1050
|
-
addIdx = idx == 0 ? 0 : idx - 1;
|
|
1051
|
-
flag = 1;
|
|
1052
|
-
} else if (
|
|
1053
|
-
tmp_el.x2 == tmp_vertices.x2 &&
|
|
1054
|
-
tmp_el.y2 == tmp_vertices.y2
|
|
1055
|
-
) {
|
|
1056
|
-
let tmp = vertices[0];
|
|
1057
|
-
vertices[0] = vertices[1];
|
|
1058
|
-
vertices[1] = tmp;
|
|
1059
|
-
addIdx = idx;
|
|
1060
|
-
flag = 1;
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
});
|
|
1064
|
-
allLines.splice(addIdx, 0, [vertices, thick]);
|
|
1065
|
-
} else {
|
|
1066
|
-
allLines.push([allAreaLines[i], thick]);
|
|
1067
|
-
}
|
|
1068
|
-
});
|
|
1069
|
-
|
|
1070
|
-
return allLines;
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
/** Get lines that wraps the area */
|
|
1074
|
-
export function getAllAreaLines(layer) {
|
|
1075
|
-
let areainfo = [];
|
|
1076
|
-
layer.areas.forEach(area => {
|
|
1077
|
-
let sz = area.vertices.size;
|
|
1078
|
-
for (var i = 0; i < sz; i++) {
|
|
1079
|
-
areainfo.push([area.vertices.get(i), area.vertices.get((i + 1) % sz)]);
|
|
1080
|
-
}
|
|
1081
|
-
});
|
|
1082
|
-
|
|
1083
|
-
return areainfo;
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
export function containLine(lines, line) {
|
|
1087
|
-
// lines: [array]
|
|
1088
|
-
let sz = lines.length;
|
|
1089
|
-
for (var i = 0; i < sz; i++) {
|
|
1090
|
-
let l = lines[i];
|
|
1091
|
-
if (
|
|
1092
|
-
(line.vertices.get(0) == l[0] && line.vertices.get(1) == l[1]) ||
|
|
1093
|
-
(line.vertices.get(1) == l[0] && line.vertices.get(0) == l[1])
|
|
1094
|
-
) {
|
|
1095
|
-
return i;
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
return -1;
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
export function buildRectFromLines(layer, lines) {
|
|
1102
|
-
let rect = [];
|
|
1103
|
-
|
|
1104
|
-
lines.forEach(line => {
|
|
1105
|
-
let vxys = []; // 0: x0, 1: y0, 2: x1, 3: y1
|
|
1106
|
-
line[0].forEach(vertex => {
|
|
1107
|
-
let vert = layer.vertices.get(vertex);
|
|
1108
|
-
vxys.push(vert.x);
|
|
1109
|
-
vxys.push(vert.y);
|
|
1110
|
-
});
|
|
1111
|
-
let thick = line[1];
|
|
1112
|
-
let x0 = vxys[0];
|
|
1113
|
-
let y0 = vxys[1];
|
|
1114
|
-
let x1 = vxys[2];
|
|
1115
|
-
let y1 = vxys[3];
|
|
1116
|
-
rect.push(getCalcRectFromLine(x0, y0, x1, y1, thick, layer));
|
|
1117
|
-
});
|
|
1118
|
-
return rect;
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
export function getRelatedVertices(x0, y0, x1, y1, layer) {
|
|
1122
|
-
let verticesArray = [];
|
|
1123
|
-
let mapVertIDtoIndex = {};
|
|
1124
|
-
|
|
1125
|
-
layer.vertices.forEach(vertex => {
|
|
1126
|
-
let verticesCount = verticesArray.push([vertex.x, vertex.y]);
|
|
1127
|
-
let latestVertexIndex = verticesCount - 1;
|
|
1128
|
-
mapVertIDtoIndex[vertex.id] = latestVertexIndex;
|
|
1129
|
-
});
|
|
1130
|
-
|
|
1131
|
-
let relVerts = [];
|
|
1132
|
-
layer.lines.some(line => {
|
|
1133
|
-
let vertID0 = line.vertices.get(0);
|
|
1134
|
-
let vertID1 = line.vertices.get(1);
|
|
1135
|
-
|
|
1136
|
-
let pt0 = {
|
|
1137
|
-
x: verticesArray[mapVertIDtoIndex[vertID0]][0],
|
|
1138
|
-
y: verticesArray[mapVertIDtoIndex[vertID0]][1]
|
|
1139
|
-
};
|
|
1140
|
-
let pt1 = {
|
|
1141
|
-
x: verticesArray[mapVertIDtoIndex[vertID1]][0],
|
|
1142
|
-
y: verticesArray[mapVertIDtoIndex[vertID1]][1]
|
|
1143
|
-
};
|
|
1144
|
-
|
|
1145
|
-
if (
|
|
1146
|
-
(Math.abs(pt0.x - x0) < EPSILON &&
|
|
1147
|
-
Math.abs(pt0.y - y0) < EPSILON &&
|
|
1148
|
-
Math.abs(pt1.x - x1) < EPSILON &&
|
|
1149
|
-
Math.abs(pt1.y - y1) < EPSILON) ||
|
|
1150
|
-
(Math.abs(pt0.x - x1) < EPSILON &&
|
|
1151
|
-
Math.abs(pt0.y - y1) < EPSILON &&
|
|
1152
|
-
Math.abs(pt1.x - x0) < EPSILON &&
|
|
1153
|
-
Math.abs(pt1.y - y0) < EPSILON)
|
|
1154
|
-
) {
|
|
1155
|
-
if (line.relatedVertices.size == 2) {
|
|
1156
|
-
let relPt0 = point(x0, y0);
|
|
1157
|
-
let relPt1 = point(x1, y1);
|
|
1158
|
-
|
|
1159
|
-
line.relatedVertices.forEach((relatedVertice, index) => {
|
|
1160
|
-
if (relatedVertice.index == undefined)
|
|
1161
|
-
relatedVertice = relatedVertice.toJSON();
|
|
1162
|
-
|
|
1163
|
-
if (relatedVertice.index == 0)
|
|
1164
|
-
relPt0 = point(relatedVertice.point.x, relatedVertice.point.y);
|
|
1165
|
-
else relPt1 = point(relatedVertice.point.x, relatedVertice.point.y);
|
|
1166
|
-
});
|
|
1167
|
-
|
|
1168
|
-
relVerts.push(relPt0);
|
|
1169
|
-
relVerts.push(relPt1);
|
|
1170
|
-
}
|
|
1171
|
-
return true;
|
|
1172
|
-
}
|
|
1173
|
-
});
|
|
1174
|
-
|
|
1175
|
-
return relVerts;
|
|
1176
|
-
}
|
|
1177
|
-
|
|
1178
|
-
export function getCalcRectFromLine(x0, y0, x1, y1, thick, layer) {
|
|
1179
|
-
// get line from vertex coordinate
|
|
1180
|
-
let relVerts = getRelatedVertices(x0, y0, x1, y1, layer);
|
|
1181
|
-
|
|
1182
|
-
let dx = x1 - x0;
|
|
1183
|
-
let dy = y1 - y0;
|
|
1184
|
-
let dl = Math.sqrt(dx * dx + dy * dy);
|
|
1185
|
-
let ox = (-dy / dl) * thick;
|
|
1186
|
-
let oy = (dx / dl) * thick;
|
|
1187
|
-
let rot = Math.atan2(dy, dx);
|
|
1188
|
-
if (relVerts.length == 2) {
|
|
1189
|
-
let vN = point(ox, oy);
|
|
1190
|
-
let vR = point(relVerts[0].x - x0, relVerts[0].y - y0);
|
|
1191
|
-
if (dotprod(vN, vR) < 0) {
|
|
1192
|
-
ox = -ox;
|
|
1193
|
-
oy = -oy;
|
|
1194
|
-
} else {
|
|
1195
|
-
rot += Math.PI;
|
|
1196
|
-
}
|
|
1197
|
-
} else {
|
|
1198
|
-
let pt0 = point(x0 + ox, y0 + oy);
|
|
1199
|
-
let pt1 = point(x1 + ox, y1 + oy);
|
|
1200
|
-
let ptC = point((pt0.x + pt1.x) / 2, (pt0.y + pt1.y) / 2);
|
|
1201
|
-
|
|
1202
|
-
let allArea = getAllArea(layer);
|
|
1203
|
-
if (isPointInArea(allArea, ptC)) {
|
|
1204
|
-
// try make rect under line
|
|
1205
|
-
let _pt0 = point(x0 - ox, y0 - oy);
|
|
1206
|
-
let _pt1 = point(x1 - ox, y1 - oy);
|
|
1207
|
-
let _ptC = point((_pt0.x + _pt1.x) / 2, (_pt0.y + _pt1.y) / 2);
|
|
1208
|
-
|
|
1209
|
-
if (!isPointInArea(allArea, _ptC)) {
|
|
1210
|
-
// only under rect is not included in area, make rect under line
|
|
1211
|
-
ox = -ox;
|
|
1212
|
-
oy = -oy;
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
|
|
1217
|
-
return {
|
|
1218
|
-
rectEnd: [point(x0 + ox / 2, y0 + oy / 2), point(x1 + ox / 2, y1 + oy / 2)],
|
|
1219
|
-
rect: [
|
|
1220
|
-
point(x0 + ox, y0 + oy),
|
|
1221
|
-
point(x1 + ox, y1 + oy),
|
|
1222
|
-
point(x1, y1),
|
|
1223
|
-
point(x0, y0)
|
|
1224
|
-
],
|
|
1225
|
-
pos: point((x0 + x1 + ox) / 2, (y0 + y1 + ox) / 2),
|
|
1226
|
-
rotRad: rot,
|
|
1227
|
-
size: { width: dl, height: thick / 2 }
|
|
1228
|
-
};
|
|
1229
|
-
}
|
|
1230
|
-
|
|
1231
|
-
export function getAllLineSnap(allLineRects, curItemRect) {
|
|
1232
|
-
let allLineSnap = [];
|
|
1233
|
-
let cur = curItemRect;
|
|
1234
|
-
if (cur === undefined || cur === null) return;
|
|
1235
|
-
else
|
|
1236
|
-
allLineRects.forEach(rect => {
|
|
1237
|
-
let cw = cur.size.width / 2;
|
|
1238
|
-
let ch = cur.size.height / 2;
|
|
1239
|
-
let cos = Math.cos(rect.rotRad);
|
|
1240
|
-
let sin = Math.sin(rect.rotRad);
|
|
1241
|
-
let ox0 = cw * cos - ch * sin; // (cw, ch) rot
|
|
1242
|
-
let oy0 = cw * sin + ch * cos;
|
|
1243
|
-
let ox1 = -cw * cos - ch * sin; // (-cw, ch) rot
|
|
1244
|
-
let oy1 = -cw * sin + ch * cos;
|
|
1245
|
-
let nrot = rect.rotRad + Math.PI;
|
|
1246
|
-
if (nrot >= Math.PI) nrot -= Math.PI * 2;
|
|
1247
|
-
let thick = rect.size.height;
|
|
1248
|
-
|
|
1249
|
-
let snap3 = itemInfo(
|
|
1250
|
-
rect.rect[2].x + ox1,
|
|
1251
|
-
rect.rect[2].y + oy1,
|
|
1252
|
-
nrot,
|
|
1253
|
-
cur.size
|
|
1254
|
-
);
|
|
1255
|
-
let snap4 = itemInfo(
|
|
1256
|
-
rect.rect[3].x + ox0,
|
|
1257
|
-
rect.rect[3].y + oy0,
|
|
1258
|
-
nrot,
|
|
1259
|
-
cur.size
|
|
1260
|
-
);
|
|
1261
|
-
if (!cur.is_corner) {
|
|
1262
|
-
allLineSnap.push(snap3);
|
|
1263
|
-
}
|
|
1264
|
-
allLineSnap.push(snap4);
|
|
1265
|
-
});
|
|
1266
|
-
|
|
1267
|
-
return allLineSnap;
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
export function validateSnaps(allSnaps, allRects) {
|
|
1271
|
-
let validSnaps = [];
|
|
1272
|
-
if (allSnaps !== undefined && allSnaps !== null && allSnaps.length > 0)
|
|
1273
|
-
allSnaps.forEach(snap => {
|
|
1274
|
-
if (validSnap(snap, allRects)) {
|
|
1275
|
-
validSnaps.push(snap);
|
|
1276
|
-
}
|
|
1277
|
-
});
|
|
1278
|
-
return validSnaps;
|
|
1279
|
-
}
|
|
1280
|
-
|
|
1281
|
-
export function validateLineSnaps(
|
|
1282
|
-
allSnaps,
|
|
1283
|
-
allItemSnap,
|
|
1284
|
-
allLineSnap,
|
|
1285
|
-
allItemRects,
|
|
1286
|
-
allLineRects,
|
|
1287
|
-
allRects
|
|
1288
|
-
) {
|
|
1289
|
-
let validSnaps = [];
|
|
1290
|
-
allSnaps.forEach(snap => {
|
|
1291
|
-
if (validSnap(snap, allRects)) {
|
|
1292
|
-
validSnaps.push(snap);
|
|
1293
|
-
} else {
|
|
1294
|
-
allItemSnap.forEach(snap => {
|
|
1295
|
-
validSnaps.push(snap);
|
|
1296
|
-
});
|
|
1297
|
-
allLineSnap.forEach(snap => {
|
|
1298
|
-
validSnaps.push(snap);
|
|
1299
|
-
});
|
|
1300
|
-
}
|
|
1301
|
-
});
|
|
1302
|
-
return validSnaps;
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
export function validSnap(snap, rects) {
|
|
1306
|
-
let snaprect = getCalcRectFromItem(snap);
|
|
1307
|
-
return rects.every(rect => {
|
|
1308
|
-
return !intersectRect(rect.rect, snaprect.rect);
|
|
1309
|
-
});
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
export function itemInfo(x, y, rotRad, size) {
|
|
1313
|
-
return { pos: { x, y }, rotRad, size };
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1316
|
-
export function intersectRect(rect1, rect2) {
|
|
1317
|
-
let ret = false;
|
|
1318
|
-
rect1 = shrinkRect(rect1);
|
|
1319
|
-
rect2 = shrinkRect(rect2);
|
|
1320
|
-
|
|
1321
|
-
ret = ret || getInterSect(rect1, rect2);
|
|
1322
|
-
|
|
1323
|
-
ret =
|
|
1324
|
-
ret ||
|
|
1325
|
-
rect1.some(pt => {
|
|
1326
|
-
return containPointInRect(pt, rect2);
|
|
1327
|
-
});
|
|
1328
|
-
ret =
|
|
1329
|
-
ret ||
|
|
1330
|
-
rect2.some(pt => {
|
|
1331
|
-
return containPointInRect(pt, rect1);
|
|
1332
|
-
});
|
|
1333
|
-
return ret;
|
|
1334
|
-
}
|
|
1335
|
-
|
|
1336
|
-
export function containPointInRect(point, rect) {
|
|
1337
|
-
// true: contain, false: not contain
|
|
1338
|
-
for (let i = 0; i < rect.length; i++) {
|
|
1339
|
-
let ni = (i + 1) % rect.length;
|
|
1340
|
-
if (crossprod(diff(point, rect[i]), diff(rect[i], rect[ni])) < 0) {
|
|
1341
|
-
return false;
|
|
1342
|
-
}
|
|
1343
|
-
}
|
|
1344
|
-
return true;
|
|
1345
|
-
}
|
|
1346
|
-
|
|
1347
|
-
export function diff(v0, v1) {
|
|
1348
|
-
return { x: v0.x - v1.x, y: v0.y - v1.y };
|
|
1349
|
-
}
|
|
1350
|
-
|
|
1351
|
-
export function crossprod(v0, v1) {
|
|
1352
|
-
return v0.x * v1.y - v0.y * v1.x;
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
export function shrinkRect(rect) {
|
|
1356
|
-
let v02x = rect[2].x - rect[0].x;
|
|
1357
|
-
let v02y = rect[2].y - rect[0].y;
|
|
1358
|
-
let d02 = Math.sqrt(v02x * v02x + v02y * v02y);
|
|
1359
|
-
let o02x = (v02x / d02) * 0.1;
|
|
1360
|
-
let o02y = (v02y / d02) * 0.1;
|
|
1361
|
-
|
|
1362
|
-
let v13x = rect[3].x - rect[1].x;
|
|
1363
|
-
let v13y = rect[3].y - rect[1].y;
|
|
1364
|
-
let d13 = Math.sqrt(v02x * v02x + v02y * v02y);
|
|
1365
|
-
let o13x = (v13x / d13) * 0.1;
|
|
1366
|
-
let o13y = (v13y / d13) * 0.1;
|
|
1367
|
-
|
|
1368
|
-
return [
|
|
1369
|
-
point(rect[0].x + o02x, rect[0].y + o02y),
|
|
1370
|
-
point(rect[1].x + o13x, rect[1].y + o13y),
|
|
1371
|
-
point(rect[2].x - o02x, rect[2].y - o02y),
|
|
1372
|
-
point(rect[3].x - o13x, rect[3].y - o13y)
|
|
1373
|
-
];
|
|
1374
|
-
}
|
|
1375
|
-
|
|
1376
|
-
export function getInterSect(shape1, shape2) {
|
|
1377
|
-
// return result of intersect of two shape
|
|
1378
|
-
let count = 0;
|
|
1379
|
-
for (let i = 0; i < shape1.length; i++) {
|
|
1380
|
-
let sl1 = { x: shape1[i].x, y: shape1[i].y };
|
|
1381
|
-
let sl2 = {
|
|
1382
|
-
x: shape1[(i + 1) % shape1.length].x,
|
|
1383
|
-
y: shape1[(i + 1) % shape1.length].y
|
|
1384
|
-
};
|
|
1385
|
-
for (let j = 0; j < shape2.length; j++) {
|
|
1386
|
-
let el1 = { x: shape2[j].x, y: shape2[j].y };
|
|
1387
|
-
let el2 = {
|
|
1388
|
-
x: shape2[(j + 1) % shape2.length].x,
|
|
1389
|
-
y: shape2[(j + 1) % shape2.length].y
|
|
1390
|
-
};
|
|
1391
|
-
let flag = getLineInterSect(
|
|
1392
|
-
sl1.x,
|
|
1393
|
-
sl1.y,
|
|
1394
|
-
sl2.x,
|
|
1395
|
-
sl2.y,
|
|
1396
|
-
el1.x,
|
|
1397
|
-
el1.y,
|
|
1398
|
-
el2.x,
|
|
1399
|
-
el2.y
|
|
1400
|
-
);
|
|
1401
|
-
if (flag) {
|
|
1402
|
-
count++;
|
|
1403
|
-
if (count > 1) return true;
|
|
1404
|
-
}
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
return false;
|
|
1408
|
-
}
|
|
1409
|
-
|
|
1410
|
-
export function getLineInterSect(s1x, s1y, e1x, e1y, s2x, s2y, e2x, e2y) {
|
|
1411
|
-
let ax = s1x;
|
|
1412
|
-
let ay = s1y;
|
|
1413
|
-
let bx = e1x - s1x;
|
|
1414
|
-
let by = e1y - s1y;
|
|
1415
|
-
let cx = s2x;
|
|
1416
|
-
let cy = s2y;
|
|
1417
|
-
let dx = e2x - s2x;
|
|
1418
|
-
let dy = e2y - s2y;
|
|
1419
|
-
|
|
1420
|
-
if (Math.abs(bx * dy - by * dx) < 0.00000001) {
|
|
1421
|
-
if (Math.abs((cx - ax) * by - (cy - ay) * bx) < 0.00000001) {
|
|
1422
|
-
let maxX = ax;
|
|
1423
|
-
let minX = ax;
|
|
1424
|
-
let maxY = ay;
|
|
1425
|
-
let minY = ay;
|
|
1426
|
-
if (maxX < e1x) maxX = e1x;
|
|
1427
|
-
if (maxX < cx) maxX = cx;
|
|
1428
|
-
if (maxX < e2x) maxX = e2x;
|
|
1429
|
-
if (minX > e1x) minX = e1x;
|
|
1430
|
-
if (minX > cx) minX = cx;
|
|
1431
|
-
if (minX > e2x) minX = e2x;
|
|
1432
|
-
if (maxY < e1y) maxY = e1y;
|
|
1433
|
-
if (maxY < cy) maxY = cy;
|
|
1434
|
-
if (maxY < e2y) maxY = e2y;
|
|
1435
|
-
if (minY > e1y) minY = e1y;
|
|
1436
|
-
if (minY > cy) minY = cy;
|
|
1437
|
-
if (minY > e2y) minX = e2y;
|
|
1438
|
-
let len = Math.sqrt(
|
|
1439
|
-
(maxX - minX) * (maxX - minX) + (maxY - minY) * (maxY - minY)
|
|
1440
|
-
);
|
|
1441
|
-
let len1 = Math.sqrt(bx * bx + by * by);
|
|
1442
|
-
let len2 = Math.sqrt(dx * dx + dy * dy);
|
|
1443
|
-
if (len < len1 + len2) {
|
|
1444
|
-
return true;
|
|
1445
|
-
} else {
|
|
1446
|
-
return false;
|
|
1447
|
-
}
|
|
1448
|
-
} else {
|
|
1449
|
-
return false;
|
|
1450
|
-
}
|
|
1451
|
-
} else {
|
|
1452
|
-
let t = (dx * (ay - cy) + dy * (cx - ax)) / (bx * dy - by * dx);
|
|
1453
|
-
let u = (bx * (cy - ay) + by * (ax - cx)) / (dx * by - dy * bx);
|
|
1454
|
-
let ret = u < 1 && u > 0 && t > 0 && t < 1;
|
|
1455
|
-
return ret;
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
|
-
export function isPointInArea(allArea, pt) {
|
|
1460
|
-
let x = pt.x;
|
|
1461
|
-
let y = pt.y;
|
|
1462
|
-
|
|
1463
|
-
let result = false;
|
|
1464
|
-
result = allArea.some(area => {
|
|
1465
|
-
let sum = 0,
|
|
1466
|
-
alpha = 0;
|
|
1467
|
-
for (let i = 0; i < area.length; i++) {
|
|
1468
|
-
let x0 = area[i].x;
|
|
1469
|
-
let y0 = area[i].y;
|
|
1470
|
-
let x1 = area[(i + 1) % area.length].x;
|
|
1471
|
-
let y1 = area[(i + 1) % area.length].y;
|
|
1472
|
-
|
|
1473
|
-
let v0 = { x: x0 - x, y: y0 - y };
|
|
1474
|
-
let v1 = { x: x1 - x, y: y1 - y };
|
|
1475
|
-
|
|
1476
|
-
if (Math.abs(v0.x) < EPSILON && Math.abs(v0.y) < EPSILON)
|
|
1477
|
-
// check if pt is area point
|
|
1478
|
-
return true;
|
|
1479
|
-
|
|
1480
|
-
// check if pt is in area line
|
|
1481
|
-
let lineLen = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
|
|
1482
|
-
let v0Len = Math.sqrt(v0.x * v0.x + v0.y * v0.y);
|
|
1483
|
-
let vPt = { x: -v0.x / v0Len, y: -v0.y / v0Len };
|
|
1484
|
-
let xE = x0 + vPt.x * lineLen;
|
|
1485
|
-
let yE = y0 + vPt.y * lineLen;
|
|
1486
|
-
|
|
1487
|
-
if (
|
|
1488
|
-
v0Len <= lineLen &&
|
|
1489
|
-
Math.abs(xE - x1) < EPSILON &&
|
|
1490
|
-
Math.abs(yE - y1) < EPSILON
|
|
1491
|
-
)
|
|
1492
|
-
return true;
|
|
1493
|
-
|
|
1494
|
-
alpha = Math.atan2(v0.x * v1.y - v1.x * v0.y, v0.x * v1.x + v0.y * v1.y);
|
|
1495
|
-
sum += alpha;
|
|
1496
|
-
}
|
|
1497
|
-
|
|
1498
|
-
if (Math.abs(Math.abs(sum) - Math.PI * 2) < EPSILON) return true;
|
|
1499
|
-
});
|
|
1500
|
-
|
|
1501
|
-
return result;
|
|
1502
|
-
}
|
|
1503
|
-
|
|
1504
|
-
export function calcSnap(
|
|
1505
|
-
allItemRect,
|
|
1506
|
-
allItemSnap,
|
|
1507
|
-
allLineRects,
|
|
1508
|
-
allLineSnap,
|
|
1509
|
-
allRect,
|
|
1510
|
-
x,
|
|
1511
|
-
y,
|
|
1512
|
-
allAreaLines
|
|
1513
|
-
) {
|
|
1514
|
-
return calcSnap2(
|
|
1515
|
-
allItemRect,
|
|
1516
|
-
allItemSnap,
|
|
1517
|
-
allLineRects,
|
|
1518
|
-
allLineSnap,
|
|
1519
|
-
allRect,
|
|
1520
|
-
x,
|
|
1521
|
-
y,
|
|
1522
|
-
allAreaLines
|
|
1523
|
-
);
|
|
1524
|
-
}
|
|
1525
|
-
|
|
1526
|
-
export function calcCreateSnap(
|
|
1527
|
-
allItemRect,
|
|
1528
|
-
allItemSnap,
|
|
1529
|
-
allLineRects,
|
|
1530
|
-
allLineSnap,
|
|
1531
|
-
allRect,
|
|
1532
|
-
x,
|
|
1533
|
-
y,
|
|
1534
|
-
polygonPoint
|
|
1535
|
-
) {
|
|
1536
|
-
// Validate required input and guard against missing `.cur`
|
|
1537
|
-
if (!allItemRect || !allItemRect.cur) return;
|
|
1538
|
-
|
|
1539
|
-
const cur = allItemRect.cur; // safe alias
|
|
1540
|
-
let cx = x;
|
|
1541
|
-
let cy = y;
|
|
1542
|
-
let ndist = 5000;
|
|
1543
|
-
let rotRad = cur.rotRad;
|
|
1544
|
-
|
|
1545
|
-
// Get candidate snaps and validate them as before
|
|
1546
|
-
let allCurSnap = getAllCurSnap(allLineRects, x, y, cur);
|
|
1547
|
-
allCurSnap = validateLineSnaps(
|
|
1548
|
-
allCurSnap,
|
|
1549
|
-
allItemSnap,
|
|
1550
|
-
allLineSnap,
|
|
1551
|
-
allItemRect,
|
|
1552
|
-
allLineRects,
|
|
1553
|
-
allRect
|
|
1554
|
-
);
|
|
1555
|
-
|
|
1556
|
-
let getSnap = false;
|
|
1557
|
-
const snapdist = [];
|
|
1558
|
-
|
|
1559
|
-
// Build distances for snaps that lie inside polygonPoint (if any)
|
|
1560
|
-
if (Array.isArray(allCurSnap)) {
|
|
1561
|
-
allCurSnap.forEach(snap => {
|
|
1562
|
-
if (!snap || !snap.pos) return;
|
|
1563
|
-
const inside = ContainsPoint(polygonPoint, snap.pos.x, snap.pos.y);
|
|
1564
|
-
if (inside) {
|
|
1565
|
-
const dx = snap.pos.x - x;
|
|
1566
|
-
const dy = snap.pos.y - y;
|
|
1567
|
-
snapdist.push(dx * dx + dy * dy);
|
|
1568
|
-
}
|
|
1569
|
-
});
|
|
1570
|
-
}
|
|
1571
|
-
|
|
1572
|
-
// Find minimum distance (Infinity if none)
|
|
1573
|
-
const edist = snapdist.length ? Math.min(...snapdist) : Infinity;
|
|
1574
|
-
|
|
1575
|
-
// Choose the snap with distance === edist
|
|
1576
|
-
if (Array.isArray(allCurSnap)) {
|
|
1577
|
-
allCurSnap.forEach(snap => {
|
|
1578
|
-
if (!snap || !snap.pos) return;
|
|
1579
|
-
const dx = snap.pos.x - x;
|
|
1580
|
-
const dy = snap.pos.y - y;
|
|
1581
|
-
const dist = dx * dx + dy * dy;
|
|
1582
|
-
if (dist === edist) {
|
|
1583
|
-
ndist = dist;
|
|
1584
|
-
cx = snap.pos.x;
|
|
1585
|
-
cy = snap.pos.y;
|
|
1586
|
-
rotRad = snap.rotRad ?? rotRad; // nullish coalescing
|
|
1587
|
-
getSnap = true;
|
|
1588
|
-
}
|
|
1589
|
-
});
|
|
1590
|
-
}
|
|
1591
|
-
|
|
1592
|
-
const crot = (rotRad / Math.PI) * 180;
|
|
1593
|
-
return { cx, cy, crot, rotRad };
|
|
1594
|
-
}
|
|
1595
|
-
|
|
1596
|
-
////////////
|
|
1597
|
-
export function calcSnap1(
|
|
1598
|
-
allItemRect,
|
|
1599
|
-
allItemSnap,
|
|
1600
|
-
allLineRects,
|
|
1601
|
-
allLineSnap,
|
|
1602
|
-
allRect,
|
|
1603
|
-
x,
|
|
1604
|
-
y
|
|
1605
|
-
) {
|
|
1606
|
-
let cx = allItemRect.cur.pos.x;
|
|
1607
|
-
let cy = allItemRect.cur.pos.y;
|
|
1608
|
-
let nx = x;
|
|
1609
|
-
let ny = y;
|
|
1610
|
-
let cursize = allItemRect.cur.size;
|
|
1611
|
-
let ndist = cursize.width * cursize.width + cursize.height * cursize.height;
|
|
1612
|
-
ndist = ndist / 4;
|
|
1613
|
-
let rotRad = allItemRect.cur.rotRad;
|
|
1614
|
-
|
|
1615
|
-
let allCurSnap = getAllCurSnap(allLineRects, x, y, allItemRect.cur);
|
|
1616
|
-
allCurSnap = validateSnaps(allCurSnap, allRect);
|
|
1617
|
-
|
|
1618
|
-
let getSnap = false;
|
|
1619
|
-
allCurSnap.forEach(snap => {
|
|
1620
|
-
let dist =
|
|
1621
|
-
(snap.pos.x - x) * (snap.pos.x - x) + (snap.pos.y - y) * (snap.pos.y - y);
|
|
1622
|
-
if (dist < ndist) {
|
|
1623
|
-
ndist = dist;
|
|
1624
|
-
nx = snap.pos.x;
|
|
1625
|
-
ny = snap.pos.y;
|
|
1626
|
-
rotRad = snap.rotRad;
|
|
1627
|
-
getSnap = true;
|
|
1628
|
-
}
|
|
1629
|
-
});
|
|
1630
|
-
|
|
1631
|
-
if (!getSnap) {
|
|
1632
|
-
allLineSnap.concat(allItemSnap).forEach(snap => {
|
|
1633
|
-
let dist =
|
|
1634
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1635
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1636
|
-
if (dist < ndist) {
|
|
1637
|
-
ndist = dist;
|
|
1638
|
-
nx = snap.pos.x;
|
|
1639
|
-
ny = snap.pos.y;
|
|
1640
|
-
rotRad = snap.rotRad;
|
|
1641
|
-
}
|
|
1642
|
-
});
|
|
1643
|
-
}
|
|
1644
|
-
|
|
1645
|
-
let rot = (rotRad / Math.PI) * 180;
|
|
1646
|
-
let ret = { nx, ny, rot, rotRad };
|
|
1647
|
-
return ret;
|
|
1648
|
-
}
|
|
1649
|
-
|
|
1650
|
-
////////////
|
|
1651
|
-
export function calcSnap2(
|
|
1652
|
-
allItemRect,
|
|
1653
|
-
allItemSnap,
|
|
1654
|
-
allLineRects,
|
|
1655
|
-
allLineSnap,
|
|
1656
|
-
allRect,
|
|
1657
|
-
x,
|
|
1658
|
-
y,
|
|
1659
|
-
allArea
|
|
1660
|
-
) {
|
|
1661
|
-
let nx = x;
|
|
1662
|
-
let ny = y;
|
|
1663
|
-
let ndist = 20;
|
|
1664
|
-
let rotRad = allItemRect.cur && allItemRect.cur.rotRad;
|
|
1665
|
-
let val = { pos: { x: x, y: y }, rotRad: rotRad };
|
|
1666
|
-
val.size = allItemRect.cur && allItemRect.cur.size;
|
|
1667
|
-
val.layoutpos = allItemRect.cur && allItemRect.cur.layoutpos;
|
|
1668
|
-
val.is_corner = allItemRect.cur && allItemRect.cur.is_corner;
|
|
1669
|
-
let curitem = getCalcRectFromItem(val);
|
|
1670
|
-
let allCurSnap = [];
|
|
1671
|
-
//if (!val.is_corner) {
|
|
1672
|
-
allCurSnap = getAllCurSnap(allLineRects, x, y, allItemRect.cur);
|
|
1673
|
-
allCurSnap = validateSnaps(allCurSnap, allRect);
|
|
1674
|
-
//}
|
|
1675
|
-
let getSnap = false;
|
|
1676
|
-
let snapdist = [];
|
|
1677
|
-
//console.log("allItemSnap", allItemSnap.filter(e => e.isSnappedLine))
|
|
1678
|
-
//console.log("~~~~start~~~~");
|
|
1679
|
-
allItemSnap
|
|
1680
|
-
.filter(e => e.isSnappedLine)
|
|
1681
|
-
.forEach(snap => {
|
|
1682
|
-
let dist =
|
|
1683
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1684
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1685
|
-
snapdist.push(dist);
|
|
1686
|
-
//console.log("dist", snap)
|
|
1687
|
-
if (isPointInArea(allArea, snap.pos) || !allArea.length)
|
|
1688
|
-
if (dist < 100) {
|
|
1689
|
-
ndist = dist;
|
|
1690
|
-
nx = snap.pos.x;
|
|
1691
|
-
ny = snap.pos.y;
|
|
1692
|
-
rotRad = snap.rotRad;
|
|
1693
|
-
getSnap = true;
|
|
1694
|
-
|
|
1695
|
-
//console.log("SUCCESS!!!!");
|
|
1696
|
-
}
|
|
1697
|
-
});
|
|
1698
|
-
//console.log("====end====");
|
|
1699
|
-
if (getSnap == false) {
|
|
1700
|
-
allCurSnap.forEach(snap => {
|
|
1701
|
-
let dist =
|
|
1702
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1703
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1704
|
-
snapdist.push(dist);
|
|
1705
|
-
if (isPointInArea(allArea, snap.pos) || !allArea.length)
|
|
1706
|
-
if (dist < ndist) {
|
|
1707
|
-
ndist = dist;
|
|
1708
|
-
nx = snap.pos.x;
|
|
1709
|
-
ny = snap.pos.y;
|
|
1710
|
-
rotRad = snap.rotRad;
|
|
1711
|
-
getSnap = true;
|
|
1712
|
-
//console.log("SUCCE!!!!");
|
|
1713
|
-
}
|
|
1714
|
-
});
|
|
1715
|
-
|
|
1716
|
-
if (
|
|
1717
|
-
!getSnap &&
|
|
1718
|
-
allLineRects.some(others => intersectRect(others.rect, curitem.rect))
|
|
1719
|
-
) {
|
|
1720
|
-
let edist = Math.min.apply(null, snapdist);
|
|
1721
|
-
allCurSnap.forEach(snap => {
|
|
1722
|
-
let dist =
|
|
1723
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1724
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1725
|
-
if (isPointInArea(allArea, snap.pos) || !allArea.length)
|
|
1726
|
-
if (dist === edist) {
|
|
1727
|
-
ndist = dist;
|
|
1728
|
-
nx = snap.pos.x;
|
|
1729
|
-
ny = snap.pos.y;
|
|
1730
|
-
rotRad = snap.rotRad;
|
|
1731
|
-
getSnap = true;
|
|
1732
|
-
}
|
|
1733
|
-
});
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
if (getSnap === false) {
|
|
1737
|
-
let nearRect = null;
|
|
1738
|
-
let minDist = Infinity;
|
|
1739
|
-
allLineRects.forEach(rect => {
|
|
1740
|
-
let e = rect.rectEnd[0];
|
|
1741
|
-
e = clone_point(e);
|
|
1742
|
-
e.x -= curitem.pos.x;
|
|
1743
|
-
e.y -= curitem.pos.y;
|
|
1744
|
-
let nRot = rect.rotRad + Math.PI / 2;
|
|
1745
|
-
let dist = Math.abs(e.x * Math.cos(nRot) + e.y * Math.sin(nRot));
|
|
1746
|
-
if (minDist > dist) {
|
|
1747
|
-
minDist = dist;
|
|
1748
|
-
nearRect = rect;
|
|
1749
|
-
}
|
|
1750
|
-
});
|
|
1751
|
-
|
|
1752
|
-
let containrect = nearRect && intersectRect(nearRect.rect, curitem.rect);
|
|
1753
|
-
if (containrect) {
|
|
1754
|
-
let filter_func = snap => {
|
|
1755
|
-
let diff = Math.abs(snap.rotRad - nearRect.rotRad - Math.PI);
|
|
1756
|
-
return diff == 0 || diff == 2 * Math.PI;
|
|
1757
|
-
};
|
|
1758
|
-
let tempSnap = allLineSnap.filter(filter_func);
|
|
1759
|
-
tempSnap = tempSnap.concat(
|
|
1760
|
-
allLineSnap.filter(snap => !filter_func(snap))
|
|
1761
|
-
);
|
|
1762
|
-
tempSnap.some(snap => {
|
|
1763
|
-
let dist =
|
|
1764
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1765
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1766
|
-
if (isPointInArea(allArea, snap.pos) || !allArea.length)
|
|
1767
|
-
if (dist < 5000) {
|
|
1768
|
-
nx = snap.pos.x;
|
|
1769
|
-
ny = snap.pos.y;
|
|
1770
|
-
rotRad = snap.rotRad;
|
|
1771
|
-
getSnap = true;
|
|
1772
|
-
return true;
|
|
1773
|
-
}
|
|
1774
|
-
return false;
|
|
1775
|
-
});
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
if (
|
|
1780
|
-
allItemRect.others.some(others =>
|
|
1781
|
-
intersectRect(others.rect, curitem.rect)
|
|
1782
|
-
)
|
|
1783
|
-
) {
|
|
1784
|
-
getSnap = false;
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
if (!getSnap) {
|
|
1788
|
-
let snapdist = [];
|
|
1789
|
-
allItemSnap.forEach(snap => {
|
|
1790
|
-
let dist =
|
|
1791
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1792
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1793
|
-
snapdist.push(dist);
|
|
1794
|
-
if (isPointInArea(allArea, snap.pos) || !allArea.length)
|
|
1795
|
-
if (dist < ndist) {
|
|
1796
|
-
ndist = dist;
|
|
1797
|
-
nx = snap.pos.x;
|
|
1798
|
-
ny = snap.pos.y;
|
|
1799
|
-
rotRad = snap.rotRad;
|
|
1800
|
-
getSnap = true;
|
|
1801
|
-
}
|
|
1802
|
-
});
|
|
1803
|
-
|
|
1804
|
-
if (
|
|
1805
|
-
!getSnap &&
|
|
1806
|
-
allItemRect.others.some(others =>
|
|
1807
|
-
intersectRect(others.rect, curitem.rect)
|
|
1808
|
-
)
|
|
1809
|
-
) {
|
|
1810
|
-
let edist = Math.min.apply(null, snapdist);
|
|
1811
|
-
allItemSnap.forEach(snap => {
|
|
1812
|
-
let dist =
|
|
1813
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1814
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1815
|
-
if (isPointInArea(allArea, snap.pos) || !allArea.length)
|
|
1816
|
-
if (dist === edist) {
|
|
1817
|
-
ndist = dist;
|
|
1818
|
-
nx = snap.pos.x;
|
|
1819
|
-
ny = snap.pos.y;
|
|
1820
|
-
rotRad = snap.rotRad;
|
|
1821
|
-
}
|
|
1822
|
-
});
|
|
1823
|
-
if (allItemRect.cur.itemInfo.name.includes('Cook Top')) {
|
|
1824
|
-
let intersects = allItemRect.others.filter(others =>
|
|
1825
|
-
intersectRect(others.rect, curitem.rect)
|
|
1826
|
-
);
|
|
1827
|
-
intersects.forEach(rect => {
|
|
1828
|
-
if (isPointInArea(allArea, rect.itemInfo) || !allArea.length)
|
|
1829
|
-
if (rect.itemInfo.layoutpos.includes(BASE_CABINET_LAYOUTPOS)) {
|
|
1830
|
-
nx = rect.itemInfo.x;
|
|
1831
|
-
ny = rect.itemInfo.y;
|
|
1832
|
-
rotRad = (rect.itemInfo.rotation * Math.PI) / 180;
|
|
1833
|
-
}
|
|
1834
|
-
});
|
|
1835
|
-
}
|
|
1836
|
-
if (
|
|
1837
|
-
allItemRect.cur.itemInfo.name.includes('Hood') ||
|
|
1838
|
-
allItemRect.cur.itemInfo.name.includes('Range') ||
|
|
1839
|
-
allItemRect.cur.itemInfo.name.includes('Cook Top')
|
|
1840
|
-
) {
|
|
1841
|
-
let intersects = allItemRect.others.filter(others =>
|
|
1842
|
-
intersectRect(others.rect, curitem.rect)
|
|
1843
|
-
);
|
|
1844
|
-
intersects.forEach(rect => {
|
|
1845
|
-
if (isPointInArea(allArea, rect.itemInfo) || !allArea.length)
|
|
1846
|
-
if (
|
|
1847
|
-
rect.itemInfo.name.includes('Hood') ||
|
|
1848
|
-
rect.itemInfo.name.includes('Range') ||
|
|
1849
|
-
rect.itemInfo.name.includes('Cook Top')
|
|
1850
|
-
) {
|
|
1851
|
-
nx = rect.itemInfo.x;
|
|
1852
|
-
ny = rect.itemInfo.y;
|
|
1853
|
-
rotRad = (rect.itemInfo.rotation * Math.PI) / 180;
|
|
1854
|
-
}
|
|
1855
|
-
});
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
}
|
|
1859
|
-
}
|
|
1860
|
-
let rot = (rotRad / Math.PI) * 180;
|
|
1861
|
-
|
|
1862
|
-
//Check case.
|
|
1863
|
-
//If item is 'blind base cabinet', it must be pulled from other 3".
|
|
1864
|
-
if (
|
|
1865
|
-
allItemRect.cur &&
|
|
1866
|
-
allItemRect.cur.itemInfo.sku_number.startsWith('BBC')
|
|
1867
|
-
) {
|
|
1868
|
-
let offset3inch = convert(3).from('in').to('cm');
|
|
1869
|
-
let tx = nx,
|
|
1870
|
-
ty = ny;
|
|
1871
|
-
if (allItemRect.cur && allItemRect.cur.itemInfo.sku_number.endsWith('-L')) {
|
|
1872
|
-
if (rot == 0 || rot == -180) {
|
|
1873
|
-
tx -= offset3inch * Math.cos(rotRad);
|
|
1874
|
-
}
|
|
1875
|
-
if (rot == 90 || rot == -90) {
|
|
1876
|
-
ty -= offset3inch * Math.sin(rotRad);
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
if (allItemRect.cur && allItemRect.cur.itemInfo.sku_number.endsWith('-R')) {
|
|
1880
|
-
if (rot == 0 || rot == -180) {
|
|
1881
|
-
tx += offset3inch * Math.cos(rotRad);
|
|
1882
|
-
}
|
|
1883
|
-
if (rot == 90 || rot == -90) {
|
|
1884
|
-
ty += offset3inch * Math.sin(rotRad);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
let t_val = {
|
|
1888
|
-
pos: { x: tx, y: ty },
|
|
1889
|
-
rotRad,
|
|
1890
|
-
size: allItemRect.cur.size,
|
|
1891
|
-
layoutpos: allItemRect.cur.layoutpos,
|
|
1892
|
-
is_corner: allItemRect.cur.is_corner
|
|
1893
|
-
};
|
|
1894
|
-
let isItemRectSect = validInterSect(allItemRect.others, t_val);
|
|
1895
|
-
let isWallRectSect = validInterSect(allLineRects, t_val);
|
|
1896
|
-
if (isItemRectSect && isWallRectSect) {
|
|
1897
|
-
nx = tx;
|
|
1898
|
-
ny = ty;
|
|
1899
|
-
}
|
|
1900
|
-
}
|
|
1901
|
-
|
|
1902
|
-
return { nx, ny, rot, rotRad };
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
////////////
|
|
1906
|
-
export function calcSnap3(
|
|
1907
|
-
allItemRect,
|
|
1908
|
-
allItemSnap,
|
|
1909
|
-
allLineRects,
|
|
1910
|
-
allLineSnap,
|
|
1911
|
-
allRect,
|
|
1912
|
-
x,
|
|
1913
|
-
y
|
|
1914
|
-
) {
|
|
1915
|
-
// let layer = scene.layers.get(layerID);
|
|
1916
|
-
// let cx = allItemRect.cur.pos.x;
|
|
1917
|
-
// let cy = allItemRect.cur.pos.y;
|
|
1918
|
-
let nx = x;
|
|
1919
|
-
let ny = y;
|
|
1920
|
-
let ndist = 20;
|
|
1921
|
-
let rotRad = allItemRect.cur.rotRad;
|
|
1922
|
-
let val = { pos: { x: x, y: y }, rotRad: rotRad };
|
|
1923
|
-
val.size = allItemRect.cur.size;
|
|
1924
|
-
val.layoutpos = allItemRect.cur.layoutpos;
|
|
1925
|
-
val.is_corner = allItemRect.cur.is_corner;
|
|
1926
|
-
let curitem = getCalcRectFromItem3D(val);
|
|
1927
|
-
let allCurSnap = getAllCurSnap(allLineRects, x, y, allItemRect.cur);
|
|
1928
|
-
allCurSnap = validateSnaps(allCurSnap, allRect);
|
|
1929
|
-
let getSnap = false;
|
|
1930
|
-
let snapdist = [];
|
|
1931
|
-
allCurSnap.forEach(snap => {
|
|
1932
|
-
let dist =
|
|
1933
|
-
(snap.pos.x - x) * (snap.pos.x - x) + (snap.pos.y - y) * (snap.pos.y - y);
|
|
1934
|
-
snapdist.push(dist);
|
|
1935
|
-
if (dist < ndist) {
|
|
1936
|
-
ndist = dist;
|
|
1937
|
-
nx = snap.pos.x;
|
|
1938
|
-
ny = snap.pos.y;
|
|
1939
|
-
rotRad = snap.rotRad;
|
|
1940
|
-
getSnap = true;
|
|
1941
|
-
} else {
|
|
1942
|
-
var i = 0;
|
|
1943
|
-
allLineRects.forEach(others => {
|
|
1944
|
-
let containrect = intersectRect(others.rect, curitem.rect);
|
|
1945
|
-
if (containrect) {
|
|
1946
|
-
let edist = Math.min.apply(null, snapdist);
|
|
1947
|
-
allCurSnap.forEach(snap => {
|
|
1948
|
-
let dist =
|
|
1949
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1950
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1951
|
-
if (dist === edist) {
|
|
1952
|
-
ndist = dist;
|
|
1953
|
-
nx = snap.pos.x;
|
|
1954
|
-
ny = snap.pos.y;
|
|
1955
|
-
rotRad = snap.rotRad;
|
|
1956
|
-
getSnap = true;
|
|
1957
|
-
}
|
|
1958
|
-
});
|
|
1959
|
-
}
|
|
1960
|
-
});
|
|
1961
|
-
}
|
|
1962
|
-
});
|
|
1963
|
-
if (getSnap === false) {
|
|
1964
|
-
allLineRects.forEach(others => {
|
|
1965
|
-
let containrect = intersectRect(others.rect, curitem.rect);
|
|
1966
|
-
if (containrect) {
|
|
1967
|
-
allLineSnap.forEach(snap => {
|
|
1968
|
-
let dist =
|
|
1969
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1970
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1971
|
-
if (dist < 5000) {
|
|
1972
|
-
nx = snap.pos.x;
|
|
1973
|
-
ny = snap.pos.y;
|
|
1974
|
-
rotRad = snap.rotRad;
|
|
1975
|
-
getSnap = true;
|
|
1976
|
-
}
|
|
1977
|
-
});
|
|
1978
|
-
}
|
|
1979
|
-
});
|
|
1980
|
-
}
|
|
1981
|
-
|
|
1982
|
-
allItemRect.others.forEach(others => {
|
|
1983
|
-
if (
|
|
1984
|
-
!(others.layoutpos === 'base' && allItemRect.cur.layoutpos === 'wall') ||
|
|
1985
|
-
!(others.layoutpos === 'wall' && allItemRect.cur.layoutpos === 'base')
|
|
1986
|
-
) {
|
|
1987
|
-
let containrect = intersectRect(others.rect, curitem.rect);
|
|
1988
|
-
if (containrect) {
|
|
1989
|
-
getSnap = false;
|
|
1990
|
-
}
|
|
1991
|
-
}
|
|
1992
|
-
});
|
|
1993
|
-
if (!getSnap) {
|
|
1994
|
-
let snapdist = [];
|
|
1995
|
-
allItemSnap.forEach(snap => {
|
|
1996
|
-
let dist =
|
|
1997
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
1998
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
1999
|
-
snapdist.push(dist);
|
|
2000
|
-
if (dist < ndist) {
|
|
2001
|
-
ndist = dist;
|
|
2002
|
-
nx = snap.pos.x;
|
|
2003
|
-
ny = snap.pos.y;
|
|
2004
|
-
rotRad = snap.rotRad;
|
|
2005
|
-
} else {
|
|
2006
|
-
allItemRect.others.forEach(others => {
|
|
2007
|
-
if (
|
|
2008
|
-
!(
|
|
2009
|
-
others.layoutpos === 'base' &&
|
|
2010
|
-
allItemRect.cur.layoutpos === 'wall'
|
|
2011
|
-
) ||
|
|
2012
|
-
!(
|
|
2013
|
-
others.layoutpos === 'wall' &&
|
|
2014
|
-
allItemRect.cur.layoutpos === 'base'
|
|
2015
|
-
)
|
|
2016
|
-
) {
|
|
2017
|
-
let containrect = intersectRect(others.rect, curitem.rect);
|
|
2018
|
-
if (containrect) {
|
|
2019
|
-
let edist = Math.min.apply(null, snapdist);
|
|
2020
|
-
allItemSnap.forEach(snap => {
|
|
2021
|
-
let dist =
|
|
2022
|
-
(snap.pos.x - x) * (snap.pos.x - x) +
|
|
2023
|
-
(snap.pos.y - y) * (snap.pos.y - y);
|
|
2024
|
-
if (dist === edist) {
|
|
2025
|
-
ndist = dist;
|
|
2026
|
-
nx = snap.pos.x;
|
|
2027
|
-
ny = snap.pos.y;
|
|
2028
|
-
rotRad = snap.rotRad;
|
|
2029
|
-
}
|
|
2030
|
-
});
|
|
2031
|
-
}
|
|
2032
|
-
}
|
|
2033
|
-
});
|
|
2034
|
-
}
|
|
2035
|
-
});
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
|
-
let rot = (rotRad / Math.PI) * 180;
|
|
2039
|
-
return { nx, ny, rot, rotRad };
|
|
2040
|
-
}
|
|
2041
|
-
|
|
2042
|
-
export function getAllCurSnap(allLineRects, x, y, curItemRect) {
|
|
2043
|
-
if (!curItemRect) return;
|
|
2044
|
-
let allCurSnap = [];
|
|
2045
|
-
let thick = LINE_THICKNESS / 2;
|
|
2046
|
-
|
|
2047
|
-
allLineRects.forEach(linerect => {
|
|
2048
|
-
//allLineRects:left, right, top, bottom line
|
|
2049
|
-
let p0 = clone_point(linerect.rect[2]); //point 2(x, y) inside of line
|
|
2050
|
-
let p1 = clone_point(linerect.rect[3]); //point 3(x, y) inside of line
|
|
2051
|
-
let q = point(x, y); // point of item
|
|
2052
|
-
let cos = Math.cos(linerect.rotRad);
|
|
2053
|
-
let sin = Math.sin(linerect.rotRad);
|
|
2054
|
-
p0.x -= (cos * curItemRect.size.width) / 2;
|
|
2055
|
-
p0.y -= (sin * curItemRect.size.width) / 2;
|
|
2056
|
-
p1.x += (cos * curItemRect.size.width) / 2;
|
|
2057
|
-
p1.y += (sin * curItemRect.size.width) / 2;
|
|
2058
|
-
let n = point(-sin, cos);
|
|
2059
|
-
let v3to0 = {
|
|
2060
|
-
x: linerect.rect[0].x - p1.x,
|
|
2061
|
-
y: linerect.rect[0].y - p1.y
|
|
2062
|
-
};
|
|
2063
|
-
let fDot = dotprod(n, v3to0);
|
|
2064
|
-
if (fDot > 0) {
|
|
2065
|
-
// normal vector is crossing the wall
|
|
2066
|
-
n.x = -n.x;
|
|
2067
|
-
n.y = -n.y;
|
|
2068
|
-
}
|
|
2069
|
-
let dist = dotprod(diff(p1, q), n);
|
|
2070
|
-
let h = point(q.x + dist * n.x, q.y + dist * n.y);
|
|
2071
|
-
let nrot = linerect.rotRad + Math.PI;
|
|
2072
|
-
if (nrot >= Math.PI) nrot -= Math.PI * 2;
|
|
2073
|
-
|
|
2074
|
-
let o = itemrectInfo(
|
|
2075
|
-
h.x + n.x * (curItemRect && curItemRect.size.height / 2),
|
|
2076
|
-
h.y + n.y * (curItemRect && curItemRect.size.height / 2),
|
|
2077
|
-
nrot,
|
|
2078
|
-
curItemRect && curItemRect.size,
|
|
2079
|
-
curItemRect && curItemRect.layoutpos,
|
|
2080
|
-
curItemRect && curItemRect.is_corner
|
|
2081
|
-
);
|
|
2082
|
-
allCurSnap.push(o);
|
|
2083
|
-
|
|
2084
|
-
nrot = nrot + Math.PI;
|
|
2085
|
-
o = itemrectInfo(
|
|
2086
|
-
h.x - n.x * (curItemRect && curItemRect.size.height / 2 + thick),
|
|
2087
|
-
h.y - n.y * (curItemRect && curItemRect.size.height / 2 + thick),
|
|
2088
|
-
nrot,
|
|
2089
|
-
curItemRect && curItemRect.size,
|
|
2090
|
-
curItemRect && curItemRect.layoutpos,
|
|
2091
|
-
curItemRect && curItemRect.is_corner
|
|
2092
|
-
);
|
|
2093
|
-
allCurSnap.push(o);
|
|
2094
|
-
});
|
|
2095
|
-
return allCurSnap;
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
export function clone_point(pt) {
|
|
2099
|
-
return point(pt.x, pt.y);
|
|
2100
|
-
}
|
|
2101
|
-
|
|
2102
|
-
export function dotprod(v0, v1) {
|
|
2103
|
-
return v0.x * v1.x + v0.y * v1.y;
|
|
2104
|
-
}
|
|
2105
|
-
|
|
2106
|
-
//////////
|
|
2107
|
-
export function validInterSect(rect, val) {
|
|
2108
|
-
let curitem = getCalcRectFromItem(val);
|
|
2109
|
-
let datas = [];
|
|
2110
|
-
rect.forEach(line => {
|
|
2111
|
-
datas.push(line);
|
|
2112
|
-
});
|
|
2113
|
-
for (let i = 0; i < datas.length; i++) {
|
|
2114
|
-
let data = datas[i];
|
|
2115
|
-
let containrect = intersectRect(data.rect, curitem.rect);
|
|
2116
|
-
if (containrect) {
|
|
2117
|
-
return false;
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
return true;
|
|
2121
|
-
}
|
|
2122
|
-
|
|
2123
|
-
let lineRect = layer => {
|
|
2124
|
-
let areainfo = [];
|
|
2125
|
-
layer.areas.forEach(area => {
|
|
2126
|
-
let sz = area.vertices.size;
|
|
2127
|
-
for (var i = 0; i < sz; i++) {
|
|
2128
|
-
areainfo.push(area.vertices.get(i));
|
|
2129
|
-
}
|
|
2130
|
-
});
|
|
2131
|
-
let rect = [];
|
|
2132
|
-
areainfo.forEach(area => {
|
|
2133
|
-
let vert = layer.vertices.get(area);
|
|
2134
|
-
rect.push(vert.x, vert.y);
|
|
2135
|
-
});
|
|
2136
|
-
return rect;
|
|
2137
|
-
};
|
|
2138
|
-
|
|
2139
|
-
export function getAllHoleRect(scene, val) {
|
|
2140
|
-
let layerID = scene.selectedLayer;
|
|
2141
|
-
let layer = scene.layers.get(layerID);
|
|
2142
|
-
let selectedItem = layer.getIn(['items', layer.selected.items.get(0)]);
|
|
2143
|
-
|
|
2144
|
-
if (selectedItem !== undefined) {
|
|
2145
|
-
if (selectedItem.category != 'cabinet') {
|
|
2146
|
-
// If selected Item type is not `cabinet` then do not snap at windows
|
|
2147
|
-
return { isSect: true, snap: null };
|
|
2148
|
-
}
|
|
2149
|
-
} else {
|
|
2150
|
-
return { isSect: false, snap: null };
|
|
2151
|
-
}
|
|
2152
|
-
|
|
2153
|
-
let holes = [];
|
|
2154
|
-
let itemRect = getCalcRectFromItem(val);
|
|
2155
|
-
layer.lines.forEach(line => {
|
|
2156
|
-
line.holes.forEach(holeID => {
|
|
2157
|
-
let hole = layer.holes.get(holeID);
|
|
2158
|
-
holes.push(hole);
|
|
2159
|
-
});
|
|
2160
|
-
});
|
|
2161
|
-
let i = 0;
|
|
2162
|
-
for (; i < holes.length; i++) {
|
|
2163
|
-
let twidth = holes[i].properties.getIn(['width', 'length']);
|
|
2164
|
-
let theight = holes[i].properties.getIn(['thickness', 'length']) + 1;
|
|
2165
|
-
let tdepth = holes[i].properties.getIn(['altitude', 'length']);
|
|
2166
|
-
//let trot = holes[i].rotation;
|
|
2167
|
-
let verticeIDs = scene.getIn([
|
|
2168
|
-
'layers',
|
|
2169
|
-
layerID,
|
|
2170
|
-
'lines',
|
|
2171
|
-
holes[i].line,
|
|
2172
|
-
'vertices'
|
|
2173
|
-
])._tail.array;
|
|
2174
|
-
let vertice0 = scene.getIn(['layers', layerID, 'vertices', verticeIDs[0]]);
|
|
2175
|
-
let vertice1 = scene.getIn(['layers', layerID, 'vertices', verticeIDs[1]]);
|
|
2176
|
-
let point0 = { x: vertice0.x, y: vertice0.y };
|
|
2177
|
-
let point1 = { x: vertice1.x, y: vertice1.y };
|
|
2178
|
-
let rotation = Math.atan2(point1.y - point0.y, point1.x - point0.x);
|
|
2179
|
-
|
|
2180
|
-
let rectInfo = getCalcRectFromLine(
|
|
2181
|
-
point0.x,
|
|
2182
|
-
point0.y,
|
|
2183
|
-
point1.x,
|
|
2184
|
-
point1.y,
|
|
2185
|
-
LINE_THICKNESS,
|
|
2186
|
-
layer
|
|
2187
|
-
);
|
|
2188
|
-
let vN = point(
|
|
2189
|
-
rectInfo.rect[0].x - rectInfo.rect[3].x,
|
|
2190
|
-
rectInfo.rect[0].y - rectInfo.rect[3].y
|
|
2191
|
-
);
|
|
2192
|
-
let lenN = Math.sqrt(vN.x * vN.x + vN.y * vN.y);
|
|
2193
|
-
vN.x /= lenN;
|
|
2194
|
-
vN.y /= lenN;
|
|
2195
|
-
|
|
2196
|
-
let hx = holes[i].x;
|
|
2197
|
-
let hy = holes[i].y;
|
|
2198
|
-
|
|
2199
|
-
hx += (theight / 2) * vN.x;
|
|
2200
|
-
hy += (theight / 2) * vN.y;
|
|
2201
|
-
|
|
2202
|
-
let tval = { pos: { x: hx, y: hy }, rotRad: rotation };
|
|
2203
|
-
tval.size = { width: twidth, height: theight };
|
|
2204
|
-
let hole_rect = getCalcRectFromItem(tval);
|
|
2205
|
-
if (intersectRect(itemRect.rect, hole_rect.rect)) {
|
|
2206
|
-
if (
|
|
2207
|
-
tdepth > itemRect.size.depth &&
|
|
2208
|
-
itemRect.layoutpos !== WALL_CABINET_LAYOUTPOS
|
|
2209
|
-
) {
|
|
2210
|
-
let dist = itemRect.size.height / 2 + theight / 2;
|
|
2211
|
-
let snap = [];
|
|
2212
|
-
let p0 = {
|
|
2213
|
-
x: hx + dist * Math.cos(rotation + Math.PI / 2),
|
|
2214
|
-
y: hy + dist * Math.sin(rotation + Math.PI / 2)
|
|
2215
|
-
};
|
|
2216
|
-
let p1 = {
|
|
2217
|
-
x: hx - dist * Math.cos(rotation + Math.PI / 2),
|
|
2218
|
-
y: hy - dist * Math.sin(rotation + Math.PI / 2)
|
|
2219
|
-
};
|
|
2220
|
-
let allArea = getAllArea(layer);
|
|
2221
|
-
if (isPointInArea(allArea, p0)) {
|
|
2222
|
-
snap.push(p0);
|
|
2223
|
-
}
|
|
2224
|
-
if (isPointInArea(allArea, p1)) {
|
|
2225
|
-
snap.push(p1);
|
|
2226
|
-
}
|
|
2227
|
-
return { isSect: true, snap };
|
|
2228
|
-
} else return { isSect: false, snap: null };
|
|
2229
|
-
}
|
|
2230
|
-
}
|
|
2231
|
-
return { isSect: true, snap: null };
|
|
2232
|
-
}
|
|
2233
|
-
|
|
2234
|
-
export function getHoleItems(layer) {
|
|
2235
|
-
let holeItems = [];
|
|
2236
|
-
layer.holes.map(hole => {
|
|
2237
|
-
let width = hole.properties.getIn(['width', 'length']);
|
|
2238
|
-
let altitude = hole.properties.getIn(['altitude', 'length']);
|
|
2239
|
-
holeItems.push({ x: hole.x, y: hole.y, width, altitude });
|
|
2240
|
-
});
|
|
2241
|
-
return holeItems;
|
|
2242
|
-
}
|
|
2243
|
-
|
|
2244
|
-
export function needSnap(curItem, othItem) {
|
|
2245
|
-
let blSnap = false;
|
|
2246
|
-
if (curItem == undefined || curItem == null) return false;
|
|
2247
|
-
let altitude = curItem.selectedItem.properties.get('altitude');
|
|
2248
|
-
let heightFromFloor = convert(altitude.get('_length'))
|
|
2249
|
-
.from(altitude.get('_unit'))
|
|
2250
|
-
.to('in');
|
|
2251
|
-
let height = curItem.cat.info.sizeinfo.height;
|
|
2252
|
-
let currentItem = {
|
|
2253
|
-
heightFromFloor,
|
|
2254
|
-
height
|
|
2255
|
-
};
|
|
2256
|
-
altitude = othItem.item.properties.get('altitude');
|
|
2257
|
-
heightFromFloor = convert(altitude.get('_length'))
|
|
2258
|
-
.from(altitude.get('_unit'))
|
|
2259
|
-
.to('in');
|
|
2260
|
-
height = othItem.cat && othItem.cat.info.sizeinfo.height;
|
|
2261
|
-
let otherItem = {
|
|
2262
|
-
heightFromFloor,
|
|
2263
|
-
height
|
|
2264
|
-
};
|
|
2265
|
-
let curFloor = currentItem.heightFromFloor;
|
|
2266
|
-
let otherFloor = otherItem.heightFromFloor;
|
|
2267
|
-
let delta;
|
|
2268
|
-
curFloor > otherFloor
|
|
2269
|
-
? (delta = otherItem.height)
|
|
2270
|
-
: (delta = currentItem.height);
|
|
2271
|
-
if (Math.abs(curFloor - otherFloor) < delta) blSnap = true;
|
|
2272
|
-
|
|
2273
|
-
if (
|
|
2274
|
-
curItem.cat.hasOwnProperty('long_name') ||
|
|
2275
|
-
(othItem.cat && othItem.cat.hasOwnProperty('long_name'))
|
|
2276
|
-
) {
|
|
2277
|
-
if (
|
|
2278
|
-
curItem.cat.long_name.includes('Hood') ||
|
|
2279
|
-
(othItem.cat && othItem.cat.long_name.includes('Hood'))
|
|
2280
|
-
)
|
|
2281
|
-
blSnap = true;
|
|
2282
|
-
if (
|
|
2283
|
-
(curItem.cat.long_name.includes('Hood') &&
|
|
2284
|
-
othItem.cat &&
|
|
2285
|
-
othItem.cat.long_name.includes('Base Cabinet')) ||
|
|
2286
|
-
(curItem.cat.long_name.includes('Base Cabinet') &&
|
|
2287
|
-
othItem.cat &&
|
|
2288
|
-
othItem.cat.long_name.includes('Hood'))
|
|
2289
|
-
)
|
|
2290
|
-
blSnap = false;
|
|
2291
|
-
if (
|
|
2292
|
-
(curItem.cat.long_name.includes('Cook Top') &&
|
|
2293
|
-
othItem.cat &&
|
|
2294
|
-
othItem.cat.long_name.includes('Cabinet')) ||
|
|
2295
|
-
(curItem.cat.long_name.includes('Cabinet') &&
|
|
2296
|
-
othItem.cat &&
|
|
2297
|
-
othItem.cat.long_name.includes('Cook Top'))
|
|
2298
|
-
)
|
|
2299
|
-
blSnap = true;
|
|
2300
|
-
}
|
|
2301
|
-
return blSnap;
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
export function isFrontWall(v0, v1) {
|
|
2305
|
-
let { x: x1, y: y1 } = v0;
|
|
2306
|
-
let { x: x2, y: y2 } = v1;
|
|
2307
|
-
let alpha = angleBetweenTwoPoints(x1, y1, x2, y2);
|
|
2308
|
-
return (
|
|
2309
|
-
(almostEqual(y1, y2) && x1 < x2) ||
|
|
2310
|
-
(-Math.PI / 2 < alpha && alpha < Math.PI / 2)
|
|
2311
|
-
);
|
|
2312
|
-
}
|
|
2313
|
-
|
|
2314
|
-
export function isBackWall(v0, v1) {
|
|
2315
|
-
let { x: x1, y: y1 } = v0;
|
|
2316
|
-
let { x: x2, y: y2 } = v1;
|
|
2317
|
-
let alpha = angleBetweenTwoPoints(x1, y1, x2, y2);
|
|
2318
|
-
return (
|
|
2319
|
-
(almostEqual(y1, y2) && x1 > x2) ||
|
|
2320
|
-
-Math.PI / 2 > alpha ||
|
|
2321
|
-
alpha > Math.PI / 2
|
|
2322
|
-
);
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
export function isLeftWall(v0, v1) {
|
|
2326
|
-
let { x: x1, y: y1 } = v0;
|
|
2327
|
-
let { x: x2, y: y2 } = v1;
|
|
2328
|
-
let alpha = angleBetweenTwoPoints(x1, y1, x2, y2);
|
|
2329
|
-
return (almostEqual(x1, x2) && y1 < y2) || (Math.PI > alpha && alpha > 0);
|
|
2330
|
-
}
|
|
2331
|
-
|
|
2332
|
-
export function isRightWall(v0, v1) {
|
|
2333
|
-
let { x: x1, y: y1 } = v0;
|
|
2334
|
-
let { x: x2, y: y2 } = v1;
|
|
2335
|
-
let alpha = angleBetweenTwoPoints(x1, y1, x2, y2);
|
|
2336
|
-
return (almostEqual(x1, x2) && y1 > y2) || (-Math.PI < alpha && alpha < 0);
|
|
2337
|
-
}
|
|
2338
|
-
|
|
2339
|
-
/**
|
|
2340
|
-
* Calculate the overlapping relationship of two lines
|
|
2341
|
-
* @param {*} srcLine // source line
|
|
2342
|
-
* @param {*} destLine // destination line
|
|
2343
|
-
* @returns overlapping status (OVERLAP_NONE | OVERLAP_SAME | OVERLAP_LINK | OVERLAP_INCLUDED | OVERLAP_SOME) and line segments of srcLine which broken with destLine
|
|
2344
|
-
* OVERLAP_NONE: two lines are not overlapped
|
|
2345
|
-
* OVERLAP_SAME: the start point and endpoint of two lines are same
|
|
2346
|
-
* OVERLAP_LINK: two lines are linked at the common point, so they can be merged to one line
|
|
2347
|
-
* OVERLAP_INCLUDED: destLine includes srcLine
|
|
2348
|
-
* OVERLAP_SOME: two lines are overlapped with some common range, then returns the trimmed segments of srcLine
|
|
2349
|
-
*
|
|
2350
|
-
* //////// test - start /////////////
|
|
2351
|
-
const p1 = { x1: 1413.1313131313132, y1: 1044.949494949495 };
|
|
2352
|
-
const p2 = { x1: 1476.2626262626263, y1: 1108.0808080808079 };
|
|
2353
|
-
const p3 = { x1: 1596.969696969697, y1: 1228.7878787878785 };
|
|
2354
|
-
const p4 = { x1: 1664.1414141414139, y1: 1295.9595959595958 };
|
|
2355
|
-
const tempRet = GeometryUtils.relationshipOfTwoOverlappedLines(
|
|
2356
|
-
{ x1: p3.x1, y1: p3.y1, x2: p1.x1, y2: p1.y1 },
|
|
2357
|
-
{ x1: p1.x1, y1: p1.y1, x2: p3.x1, y2: p3.y1 }
|
|
2358
|
-
);
|
|
2359
|
-
console.log(tempRet);
|
|
2360
|
-
//////// test - end /////////////
|
|
2361
|
-
|
|
2362
|
-
*/
|
|
2363
|
-
export function relationshipOfTwoOverlappedLines(srcLine, destLine) {
|
|
2364
|
-
const INFINITY = 1000000;
|
|
2365
|
-
// geometric equation of srcLine
|
|
2366
|
-
const dx1 = MathUtils.toFixedFloat(srcLine.x2 - srcLine.x1, 2);
|
|
2367
|
-
const dy1 = MathUtils.toFixedFloat(srcLine.y2 - srcLine.y1, 2);
|
|
2368
|
-
const a1 = dx1 === 0 ? INFINITY : MathUtils.toFixedFloat(dy1 / dx1, 2);
|
|
2369
|
-
const b1 =
|
|
2370
|
-
a1 === INFINITY
|
|
2371
|
-
? MathUtils.toFixedFloat(srcLine.x1, 2)
|
|
2372
|
-
: MathUtils.toFixedFloat(srcLine.y1 - a1 * srcLine.x1, 2);
|
|
2373
|
-
// geometric equation of destLine
|
|
2374
|
-
const dx2 = MathUtils.toFixedFloat(destLine.x2 - destLine.x1, 2);
|
|
2375
|
-
const dy2 = MathUtils.toFixedFloat(destLine.y2 - destLine.y1, 2);
|
|
2376
|
-
const a2 = dx2 === 0 ? INFINITY : MathUtils.toFixedFloat(dy2 / dx2, 2);
|
|
2377
|
-
const b2 =
|
|
2378
|
-
a2 === INFINITY
|
|
2379
|
-
? MathUtils.toFixedFloat(destLine.x1, 2)
|
|
2380
|
-
: MathUtils.toFixedFloat(destLine.y1 - a2 * destLine.x1, 2);
|
|
2381
|
-
|
|
2382
|
-
if (MathUtils.fAbs(a1) - MathUtils.fAbs(a2) !== 0)
|
|
2383
|
-
// two lines are not parallel
|
|
2384
|
-
return { result: OVERLAP_NONE };
|
|
2385
|
-
if (b1 !== b2)
|
|
2386
|
-
// two lines are parallel but not overlap
|
|
2387
|
-
return { result: OVERLAP_NONE };
|
|
2388
|
-
|
|
2389
|
-
// parametric equation of destLine
|
|
2390
|
-
const sk1 =
|
|
2391
|
-
dx1 === 0
|
|
2392
|
-
? INFINITY
|
|
2393
|
-
: MathUtils.toFixedFloat(
|
|
2394
|
-
MathUtils.toFixedFloat(destLine.x1 - srcLine.x1, 2) / dx1,
|
|
2395
|
-
2
|
|
2396
|
-
);
|
|
2397
|
-
const sk2 =
|
|
2398
|
-
dy1 === 0
|
|
2399
|
-
? INFINITY
|
|
2400
|
-
: MathUtils.toFixedFloat(
|
|
2401
|
-
MathUtils.toFixedFloat(destLine.y1 - srcLine.y1, 2) / dy1,
|
|
2402
|
-
2
|
|
2403
|
-
);
|
|
2404
|
-
const ek1 =
|
|
2405
|
-
dx1 === 0
|
|
2406
|
-
? INFINITY
|
|
2407
|
-
: MathUtils.toFixedFloat(
|
|
2408
|
-
MathUtils.toFixedFloat(destLine.x2 - srcLine.x1, 2) / dx1,
|
|
2409
|
-
2
|
|
2410
|
-
);
|
|
2411
|
-
const ek2 =
|
|
2412
|
-
dy1 === 0
|
|
2413
|
-
? INFINITY
|
|
2414
|
-
: MathUtils.toFixedFloat(
|
|
2415
|
-
MathUtils.toFixedFloat(destLine.y2 - srcLine.y1, 2) / dy1,
|
|
2416
|
-
2
|
|
2417
|
-
);
|
|
2418
|
-
|
|
2419
|
-
if (
|
|
2420
|
-
sk1 !== INFINITY &&
|
|
2421
|
-
sk2 !== INFINITY &&
|
|
2422
|
-
ek1 !== INFINITY &&
|
|
2423
|
-
ek2 !== INFINITY &&
|
|
2424
|
-
(sk1 !== sk2 || ek1 !== ek2)
|
|
2425
|
-
)
|
|
2426
|
-
// destLine does not overlap with srcLine
|
|
2427
|
-
return { result: OVERLAP_NONE };
|
|
2428
|
-
|
|
2429
|
-
// parameter of destLine on the start and end points
|
|
2430
|
-
const sk = Math.min(sk1, sk2);
|
|
2431
|
-
const ek = Math.min(ek1, ek2);
|
|
2432
|
-
|
|
2433
|
-
// check the relationship between srcLine and destLine
|
|
2434
|
-
if ((sk < 0 && ek < 0) || (sk > 1 && ek > 1))
|
|
2435
|
-
// not overlap
|
|
2436
|
-
return { result: OVERLAP_NONE };
|
|
2437
|
-
if ((sk === 0 && ek === 1) || (sk === 1 && ek === 0))
|
|
2438
|
-
// same lines
|
|
2439
|
-
return { result: OVERLAP_SAME };
|
|
2440
|
-
if ((sk <= 0 && ek >= 1) || (sk >= 1 && ek <= 0))
|
|
2441
|
-
// destLine includes srcLine
|
|
2442
|
-
return { result: OVERLAP_INCLUDED };
|
|
2443
|
-
if (
|
|
2444
|
-
(sk === 0 && ek < 0) ||
|
|
2445
|
-
(sk === 1 && ek > 1) ||
|
|
2446
|
-
(ek === 0 && sk < 0) ||
|
|
2447
|
-
(ek === 1 && sk > 1)
|
|
2448
|
-
) {
|
|
2449
|
-
// linked with one common point
|
|
2450
|
-
let linkedLine;
|
|
2451
|
-
if (sk === 0 && ek < 0) {
|
|
2452
|
-
// destE destS srcS srcE
|
|
2453
|
-
// |----------|------------|
|
|
2454
|
-
linkedLine = {
|
|
2455
|
-
x1: destLine.x2,
|
|
2456
|
-
y1: destLine.y2,
|
|
2457
|
-
x2: srcLine.x2,
|
|
2458
|
-
y2: srcLine.y2
|
|
2459
|
-
};
|
|
2460
|
-
} else if (sk === 1 && ek > 1) {
|
|
2461
|
-
// srcS srcE destS destE
|
|
2462
|
-
// |----------|------------|
|
|
2463
|
-
linkedLine = {
|
|
2464
|
-
x1: srcLine.x1,
|
|
2465
|
-
y1: srcLine.y1,
|
|
2466
|
-
x2: destLine.x2,
|
|
2467
|
-
y2: destLine.y2
|
|
2468
|
-
};
|
|
2469
|
-
} else if (ek === 0 && sk < 0) {
|
|
2470
|
-
// destS destE srcS srcE
|
|
2471
|
-
// |----------|------------|
|
|
2472
|
-
linkedLine = {
|
|
2473
|
-
x1: destLine.x1,
|
|
2474
|
-
y1: destLine.y1,
|
|
2475
|
-
x2: srcLine.x2,
|
|
2476
|
-
y2: srcLine.y2
|
|
2477
|
-
};
|
|
2478
|
-
} else if (ek === 1 && sk > 1) {
|
|
2479
|
-
// srcS srcE destE destS
|
|
2480
|
-
// |----------|------------|
|
|
2481
|
-
linkedLine = {
|
|
2482
|
-
x1: srcLine.x1,
|
|
2483
|
-
y1: srcLine.y1,
|
|
2484
|
-
x2: destLine.x1,
|
|
2485
|
-
y2: destLine.y1
|
|
2486
|
-
};
|
|
2487
|
-
}
|
|
2488
|
-
return { result: OVERLAP_LINK, linkedLine };
|
|
2489
|
-
}
|
|
2490
|
-
|
|
2491
|
-
let trimmedSegment1 = null;
|
|
2492
|
-
let trimmedSegment2 = null;
|
|
2493
|
-
const ret = { result: OVERLAP_SOME, trimmedSegs: [] };
|
|
2494
|
-
if (0 <= sk && sk <= 1 && 0 <= ek && ek <= 1) {
|
|
2495
|
-
// srcLine includes destLine
|
|
2496
|
-
if (sk < ek) {
|
|
2497
|
-
// srcS destS destE srcE
|
|
2498
|
-
// |------|---------|-------|
|
|
2499
|
-
trimmedSegment1 = {
|
|
2500
|
-
x1: srcLine.x1,
|
|
2501
|
-
y1: srcLine.y1,
|
|
2502
|
-
x2: destLine.x1,
|
|
2503
|
-
y2: destLine.y1
|
|
2504
|
-
};
|
|
2505
|
-
if (ek < 1)
|
|
2506
|
-
trimmedSegment2 = {
|
|
2507
|
-
x1: destLine.x2,
|
|
2508
|
-
y1: destLine.y2,
|
|
2509
|
-
x2: srcLine.x2,
|
|
2510
|
-
y2: srcLine.y2
|
|
2511
|
-
};
|
|
2512
|
-
} else {
|
|
2513
|
-
// srcS destE destS srcE
|
|
2514
|
-
// |------|---------|-------|
|
|
2515
|
-
trimmedSegment1 = {
|
|
2516
|
-
x1: srcLine.x1,
|
|
2517
|
-
y1: srcLine.y1,
|
|
2518
|
-
x2: destLine.x2,
|
|
2519
|
-
y2: destLine.y2
|
|
2520
|
-
};
|
|
2521
|
-
if (sk < 1)
|
|
2522
|
-
trimmedSegment2 = {
|
|
2523
|
-
x1: destLine.x1,
|
|
2524
|
-
y1: destLine.y1,
|
|
2525
|
-
x2: srcLine.x2,
|
|
2526
|
-
y2: srcLine.y2
|
|
2527
|
-
};
|
|
2528
|
-
}
|
|
2529
|
-
} else {
|
|
2530
|
-
// srcLine and destLine are overlapped with some range
|
|
2531
|
-
if (sk < 0) {
|
|
2532
|
-
// destS srcS destE srcE
|
|
2533
|
-
// |------|---------|-------|
|
|
2534
|
-
trimmedSegment1 = {
|
|
2535
|
-
x1: destLine.x2,
|
|
2536
|
-
y1: destLine.y2,
|
|
2537
|
-
x2: srcLine.x2,
|
|
2538
|
-
y2: srcLine.y2
|
|
2539
|
-
};
|
|
2540
|
-
} else if (ek < 0) {
|
|
2541
|
-
// destE srcS destS srcE
|
|
2542
|
-
// |------|---------|-------|
|
|
2543
|
-
trimmedSegment1 = {
|
|
2544
|
-
x1: destLine.x1,
|
|
2545
|
-
y1: destLine.y1,
|
|
2546
|
-
x2: srcLine.x2,
|
|
2547
|
-
y2: srcLine.y2
|
|
2548
|
-
};
|
|
2549
|
-
} else if (sk > 1) {
|
|
2550
|
-
// srcS destE srcE destS
|
|
2551
|
-
// |------|---------|-------|
|
|
2552
|
-
trimmedSegment1 = {
|
|
2553
|
-
x1: srcLine.x1,
|
|
2554
|
-
y1: srcLine.y1,
|
|
2555
|
-
x2: destLine.x2,
|
|
2556
|
-
y2: destLine.y2
|
|
2557
|
-
};
|
|
2558
|
-
} else if (ek > 1) {
|
|
2559
|
-
// srcS destS srcE destE
|
|
2560
|
-
// |------|---------|-------|
|
|
2561
|
-
trimmedSegment1 = {
|
|
2562
|
-
x1: srcLine.x1,
|
|
2563
|
-
y1: srcLine.y1,
|
|
2564
|
-
x2: destLine.x1,
|
|
2565
|
-
y2: destLine.y1
|
|
2566
|
-
};
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
|
-
if (trimmedSegment1 !== null) ret.trimmedSegs.push(trimmedSegment1);
|
|
2570
|
-
if (trimmedSegment2 !== null) ret.trimmedSegs.push(trimmedSegment2);
|
|
2571
|
-
return ret;
|
|
2572
|
-
}
|