!2285 功能:三维放样(Sweep)(线条)

pull/2302/head
ChenX 1 year ago
parent 4e0d808ed3
commit 2376956cb4

@ -0,0 +1,68 @@
import { Vector3 } from "three";
import { HardwareTopline } from "../../src/DatabaseServices/Hardware/HardwareTopline";
import { LoadEntityFromFileData } from "../Utils/LoadEntity.util";
describe("三维扫掠夹点拉伸及拖拽", () =>
{
test("连接点拖拽", () =>
{
let data = { "file": [1, "HardwareTopline", 10, 2, 289, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 2, "Polyline", 10, 2, 0, 0, 1, 7, 71, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, 2, 4, [0, -1759.3364756864237], 0, [2540.6486638849437, -1754.5919838318846], 0, [2646.5114137277756, 2782.5795590546654], 0, [0, 2676.716809211834], 0, false, "Polyline", 10, 2, 0, 0, 1, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [1756.7709279402495, 2676.716809211834], 0, [-1452.394394942868, 2676.716809211834], 0, [-1452.394394942868, -1759.3364756864237], 0, [1756.7709279402495, -1759.3364756864237], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": -1558.2571447857001, "y": -2754.976206098365, "z": -1865.1992255292557 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
en.MoveGripPoints([6, 7], new Vector3(0, 3000, 3000));
const pathGripPts = en.GetGripPoints();
for (let pt of pathGripPts)
expect(pt).toMatchSnapshot();
});
test("中间点拖拽", () =>
{
let data = { "file": [1, "HardwareTopline", 10, 2, 289, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 2, "Polyline", 10, 2, 0, 0, 1, 7, 71, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, 2, 4, [0, -1759.3364756864237], 0, [2540.6486638849437, -1754.5919838318846], 0, [2646.5114137277756, 2782.5795590546654], 0, [0, 2676.716809211834], 0, false, "Polyline", 10, 2, 0, 0, 1, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [1756.7709279402495, 2676.716809211834], 0, [-1452.394394942868, 2676.716809211834], 0, [-1452.394394942868, -1759.3364756864237], 0, [1756.7709279402495, -1759.3364756864237], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": -1558.2571447857001, "y": -2754.976206098365, "z": -1865.1992255292557 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
en.MoveGripPoints([5], new Vector3(0, 0, 2500));
const pathGripPts = en.GetGripPoints();
for (let pt of pathGripPts)
expect(pt).toMatchSnapshot();
});
test("三线段连接点拖拽", () =>
{
let data = { "file": [1, "HardwareTopline", 10, 2, 290, 0, 1, 7, 71, [0.08710264982404563, -0.995587843197948, -0.03489949670250097, 0, 0.9961946980917455, 0.08715574274765814, 0, 0, 0.003041691556625918, -0.03476669358110182, 0.9993908270190958, 0, 4585.502577142352, -3723.710151480106, 2182.6332735674614, 1], 0, 0, 1, [0.08710264982404563, -0.995587843197948, -0.03489949670250097, 0, 0.9961946980917455, 0.08715574274765814, 0, 0, 0.003041691556625918, -0.03476669358110182, 0.9993908270190958, 0, 4585.502577142352, -3723.710151480106, 2182.6332735674614, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 4, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [2079.4342344794095, 1585.0706627478594], 0, [5161.537758750944, 1369.5366844918453], 0, [5161.537758750944, -1871.4511341125599], 0, [2317.886631016043, -1896.850481283555], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, 2, 2, [1830.4094117647062, -3266.3871657754003], 0, [0, -3266.3871657754003], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [0, -1, 0, 0, 1.2246467991473532e-16, 0, -1, 0, 1, 0, 1.2246467991473532e-16, 0, 487.47721925133686, 0, -1896.850481283555, 1], 0, 0, 1, [0, -1, 0, 0, 1.2246467991473532e-16, 0, -1, 0, 1, 0, 1.2246467991473532e-16, 0, 487.47721925133686, 0, -1896.850481283555, 1], 0, 0, 1, 2, 4, [0, 0], 0, [2374.4326701394516, 0], 0, [2374.4326701394516, -3259.051966436142], 0, [0, -3740.6774573715625], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, 2, 2, [-5.808380874699053e-14, 474.29029159616266], 0, [1591.957015228073, 215.53397825601405], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 2147.057632809272, "y": -9249.31319428957, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
en.MoveGripPoints([9, 10], new Vector3(70, -800, 2000));
const pathGripPts = en.GetGripPoints();
for (let pt of pathGripPts)
expect(pt).toMatchSnapshot();
});
test("三线段中间点拖拽", () =>
{
let data = { "file": [1, "HardwareTopline", 10, 2, 290, 0, 1, 7, 71, [0.08710264982404563, -0.995587843197948, -0.03489949670250097, 0, 0.9961946980917455, 0.08715574274765814, 0, 0, 0.003041691556625918, -0.03476669358110182, 0.9993908270190958, 0, 4585.502577142352, -3723.710151480106, 2182.6332735674614, 1], 0, 0, 1, [0.08710264982404563, -0.995587843197948, -0.03489949670250097, 0, 0.9961946980917455, 0.08715574274765814, 0, 0, 0.003041691556625918, -0.03476669358110182, 0.9993908270190958, 0, 4585.502577142352, -3723.710151480106, 2182.6332735674614, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 4, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [2079.4342344794095, 1585.0706627478594], 0, [5161.537758750944, 1369.5366844918453], 0, [5161.537758750944, -1871.4511341125599], 0, [2317.886631016043, -1896.850481283555], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, 2, 2, [1830.4094117647062, -3266.3871657754003], 0, [0, -3266.3871657754003], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [0, -1, 0, 0, 1.2246467991473532e-16, 0, -1, 0, 1, 0, 1.2246467991473532e-16, 0, 487.47721925133686, 0, -1896.850481283555, 1], 0, 0, 1, [0, -1, 0, 0, 1.2246467991473532e-16, 0, -1, 0, 1, 0, 1.2246467991473532e-16, 0, 487.47721925133686, 0, -1896.850481283555, 1], 0, 0, 1, 2, 4, [0, 0], 0, [2374.4326701394516, 0], 0, [2374.4326701394516, -3259.051966436142], 0, [0, -3740.6774573715625], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, 2, 2, [-5.808380874699053e-14, 474.29029159616266], 0, [1591.957015228073, 215.53397825601405], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 2147.057632809272, "y": -9249.31319428957, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
en.MoveGripPoints([18], new Vector3(10, -1000, 2500));
const pathGripPts = en.GetGripPoints();
for (let pt of pathGripPts)
expect(pt).toMatchSnapshot();
});
test("二线段拉伸", () =>
{
let data = { "file": [1, "HardwareTopline", 10, 2, 289, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 2, "Polyline", 10, 2, 0, 0, 1, 7, 71, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, 2, 4, [0, -1759.3364756864237], 0, [2540.6486638849437, -1754.5919838318846], 0, [2646.5114137277756, 2782.5795590546654], 0, [0, 2676.716809211834], 0, false, "Polyline", 10, 2, 0, 0, 1, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [1756.7709279402495, 2676.716809211834], 0, [-1452.394394942868, 2676.716809211834], 0, [-1452.394394942868, -1759.3364756864237], 0, [1756.7709279402495, -1759.3364756864237], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": -1558.2571447857001, "y": -2754.976206098365, "z": -1865.1992255292557 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
en.MoveStretchPoints([6, 5], new Vector3(-2500, 0, 0));
const pathGripPts = en.GetStretchPoints();
for (let pt of pathGripPts)
expect(pt).toMatchSnapshot();
});
test("三线段拉伸", () =>
{
let data = { "file": [1, "HardwareTopline", 10, 2, 290, 0, 1, 7, 71, [0.08710264982404563, -0.995587843197948, -0.03489949670250097, 0, 0.9961946980917455, 0.08715574274765814, 0, 0, 0.003041691556625918, -0.03476669358110182, 0.9993908270190958, 0, 4585.502577142352, -3723.710151480106, 2182.6332735674614, 1], 0, 0, 1, [0.08710264982404563, -0.995587843197948, -0.03489949670250097, 0, 0.9961946980917455, 0.08715574274765814, 0, 0, 0.003041691556625918, -0.03476669358110182, 0.9993908270190958, 0, 4585.502577142352, -3723.710151480106, 2182.6332735674614, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 4, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [2079.4342344794095, 1585.0706627478594], 0, [5161.537758750944, 1369.5366844918453], 0, [5161.537758750944, -1871.4511341125599], 0, [2317.886631016043, -1896.850481283555], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, 2, 2, [1830.4094117647062, -3266.3871657754003], 0, [0, -3266.3871657754003], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [0, -1, 0, 0, 1.2246467991473532e-16, 0, -1, 0, 1, 0, 1.2246467991473532e-16, 0, 487.47721925133686, 0, -1896.850481283555, 1], 0, 0, 1, [0, -1, 0, 0, 1.2246467991473532e-16, 0, -1, 0, 1, 0, 1.2246467991473532e-16, 0, 487.47721925133686, 0, -1896.850481283555, 1], 0, 0, 1, 2, 4, [0, 0], 0, [2374.4326701394516, 0], 0, [2374.4326701394516, -3259.051966436142], 0, [0, -3740.6774573715625], 0, false, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 487.4772192513367, 0, 1369.5366844918453, 1], 0, 0, 1, 2, 2, [-5.808380874699053e-14, 474.29029159616266], 0, [1591.957015228073, 215.53397825601405], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 2147.057632809272, "y": -9249.31319428957, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
en.MoveStretchPoints([11, 10, 9, 8, 1, 0], new Vector3(0, 0, 2000));
const pathGripPts = en.GetStretchPoints();
for (let pt of pathGripPts)
expect(pt).toMatchSnapshot();
});
});

@ -59,11 +59,21 @@ describe("顶线分段测试", () =>
}); });
test("不闭合多补圆弧", () => test("不闭合多补圆弧", () =>
{ {
let data = { "file": [1, "HardwareTopline", 8, 2, 461, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 9, [45751.96592203299, 3086.036062563707], 0.22239155538431857, [52423.0828344913, 5938.5569393828955], 1.1461811427928006, [56463.47934476306, 3849.018445843789], 1.043480940008842, [62001.088374224215, 3387.691765452039], 0.8769933217842865, [68693.87601580269, 3758.4758746386747], 0.798237664392203, [75267.09679427171, 4091.702169937928], -0.8843311793277688, [80944.03676807143, 3824.3355122590892], -1.0886924073122075, [88681.92945847644, 2000.566713469759], -0.803057870546459, [94187.65216324253, -492.2642729771228], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 45750.62233582299, "y": -504.6289351196049, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; let data =
{ "file": [1, "HardwareTopline", 8, 2, 461, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 1, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -287.8749030927833, -1610.1774753266122, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -259.0799031476998, 7.263922518159916, 0, 1], 0, 2, 12, [327.8749030927833, 1710.1774753266122], 0, [305.5142233177854, 1710.1774753266122], 0, [265.5142233177854, 1630.1774753266122], 0, [227.8749030927833, 1630.1774753266122], 0, [227.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1610.1774753266122], 0, [287.8749030927833, 1630.1774753266122], 0, [293.72274470531937, 1641.8731585516844], -0.4817330338808767, [307.8749030927833, 1670.1774753266122], 0, [315.06369878080005, 1684.5550667026457], -1.000000000000003, [322.30959178698555, 1699.0468527150167], 0, [327.8749030927833, 1710.1774753266122], 0, false, "Polyline", 8, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 2, 9, [45751.96592203299, 3086.036062563707], 0.22239155538431857, [52423.0828344913, 5938.5569393828955], 1.1461811427928006, [56463.47934476306, 3849.018445843789], 1.043480940008842, [62001.088374224215, 3387.691765452039], 0.8769933217842865, [68693.87601580269, 3758.4758746386747], 0.798237664392203, [75267.09679427171, 4091.702169937928], -0.8843311793277688, [80944.03676807143, 3824.3355122590892], -1.0886924073122075, [88681.92945847644, 2000.566713469759], -0.803057870546459, [94187.65216324253, -492.2642729771228], 0, false, 1, 0, "0", "2", "", "", "", "", "", "", "", "", "", 0], "basePt": { "x": 45750.62233582299, "y": -504.6289351196049, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline; let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
let sgs = en.Segmentations; let sgs = en.Segmentations;
for (let sg of sgs) for (let sg of sgs)
expect(sg.Length).toMatchSnapshot(); expect(sg.Length).toMatchSnapshot();
}); });
test("三维顶线", () =>
{
let data =
{ "file": [1, "HardwareTopline", 10, 2, 289, 0, 1, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4796.814917280106, -649.6766791599803, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 4796.814917280106, -649.6766791599803, 0, 1], 0, 0, 1, 2, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1794.6800494579688, -752.3551866479207, 0, 1], 0, 0, 1, 2, 12, [1691.4177159478995, 702.8822712717154], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1714.7698425753852, 679.5301446442261], 0, [1746.210156625953, 710.970458694799], 0, [1775.6109646391687, 681.5696506815787], 0, [1811.5243923180442, 717.4830783604598], 0, [1851.9100343613813, 677.0974363171161], 0, [1851.9100343613813, 677.0974363171161], 0, [1900.5427993008007, 725.7302012565432], 0, [1799.7364779468508, 826.5365226105092], 0, [1691.4177159478995, 702.8822712717154], 0, false, 2, "Polyline", 10, 2, 239, 1, 1, 7, 71, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 1756.7709279402495, 0, 0, 1], 0, 0, 1, 2, 4, [0, -1759.3364756864237], 0, [2540.6486638849437, -1754.5919838318846], 0, [2540.6486638849437, 2676.716809211834], 0, [0, 2676.716809211834], 0, false, "Polyline", 10, 2, 242, 1, 1, 7, 71, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1], 0, 0, 1, 2, 4, [1756.7709279402495, 2676.716809211834], 0, [-1452.394394942868, 2676.716809211834], 0, [-1452.394394942868, -1759.3364756864237], 0, [1756.7709279402495, -1759.3364756864237], 0, false, 1, 0, "0", "2", "", "", "", "23", "", "", "", "", "", 0], "basePt": { "x": 3238.557772494406, "y": -3296.1880928879395, "z": -1865.1992255292557 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let en = LoadEntityFromFileData(data)[0] as HardwareTopline;
let sgs = en.Segmentations;
for (let sg of sgs)
expect(sg.Length).toMatchSnapshot();
});
}); });

@ -0,0 +1,705 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 1`] = `
Vector3 {
"x": 4779.153543829856,
"y": -5937.150829198574,
"z": 6225.898121747388,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 2`] = `
Vector3 {
"x": 4909.202722547994,
"y": -7423.619743878054,
"z": 4798.549362535392,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 3`] = `
Vector3 {
"x": 5039.251901266132,
"y": -8910.088658557535,
"z": 3371.2006033233943,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 4`] = `
Vector3 {
"x": 5034.322858624644,
"y": -8853.749443362783,
"z": 1751.6938551264584,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 5`] = `
Vector3 {
"x": 5029.393815983156,
"y": -8797.410228168032,
"z": 132.187106929523,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 6`] = `
Vector3 {
"x": 4905.510413292816,
"y": -7381.416455973404,
"z": 169.1161662197635,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 7`] = `
Vector3 {
"x": 4781.627010602477,
"y": -5965.4226837787755,
"z": 206.045225510004,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 8`] = `
Vector3 {
"x": 4781.627010602477,
"y": -5965.4226837787755,
"z": 206.045225510004,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 9`] = `
Vector3 {
"x": 4701.9102555886875,
"y": -5054.2560045647515,
"z": 237.9854091250586,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 10`] = `
Vector3 {
"x": 4622.193500574898,
"y": -4143.0893253507265,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 11`] = `
Vector3 {
"x": 4622.193500574898,
"y": -4143.0893253507265,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 12`] = `
Vector3 {
"x": 3439.4948820905242,
"y": -4246.562046835881,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 13`] = `
Vector3 {
"x": 2256.79626360615,
"y": -4350.034768321036,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 14`] = `
Vector3 {
"x": 2261.752779030607,
"y": -4406.687998862022,
"z": 1898.4589127575264,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 15`] = `
Vector3 {
"x": 2266.709294455064,
"y": -4463.341229403009,
"z": 3526.992232774939,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 16`] = `
Vector3 {
"x": 3453.9931103730432,
"y": -4412.277554402447,
"z": 5033.523769555613,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 17`] = `
Vector3 {
"x": 4641.276926291022,
"y": -4361.213879401886,
"z": 6540.055306336288,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 18`] = `
Vector3 {
"x": 4641.276926291022,
"y": -4361.2138794018865,
"z": 6540.055306336288,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 19`] = `
Vector3 {
"x": 4710.215235060439,
"y": -5149.18235430023,
"z": 6382.976714041839,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段中间点拖拽 20`] = `
Vector3 {
"x": 4779.153543829856,
"y": -5937.150829198574,
"z": 6225.898121747388,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 1`] = `
Vector3 {
"x": 4777.527782432507,
"y": -5918.5682913950595,
"z": 5691.731196145292,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 2`] = `
Vector3 {
"x": 5045.331578546759,
"y": -8979.579687859008,
"z": 5368.764653583218,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 3`] = `
Vector3 {
"x": 5029.393815983156,
"y": -8797.410228168032,
"z": 132.187106929523,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 4`] = `
Vector3 {
"x": 4781.627010602477,
"y": -5965.4226837787755,
"z": 206.045225510004,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 5`] = `
Vector3 {
"x": 4781.627010602477,
"y": -5965.4226837787755,
"z": 206.045225510004,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 6`] = `
Vector3 {
"x": 4622.193500574898,
"y": -4143.0893253507265,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 7`] = `
Vector3 {
"x": 4622.193500574898,
"y": -4143.0893253507265,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 8`] = `
Vector3 {
"x": 2256.79626360615,
"y": -4350.034768321036,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 9`] = `
Vector3 {
"x": 2272.7889717356907,
"y": -4532.832258704482,
"z": 5524.556283034763,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 10`] = `
Vector3 {
"x": 4639.651164893673,
"y": -4342.631341598372,
"z": 6005.888380734192,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 11`] = `
Vector3 {
"x": 4639.651164893673,
"y": -4342.631341598372,
"z": 6005.888380734192,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段拉伸 12`] = `
Vector3 {
"x": 4777.527782432507,
"y": -5918.56829139506,
"z": 5691.731196145292,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 1`] = `
Vector3 {
"x": 4771.44810515188,
"y": -5849.077262093586,
"z": 3694.167145885469,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 2`] = `
Vector3 {
"x": 4905.350003209006,
"y": -7379.582960325561,
"z": 3532.6838746044314,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 3`] = `
Vector3 {
"x": 5039.251901266132,
"y": -8910.088658557535,
"z": 3371.2006033233943,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 4`] = `
Vector3 {
"x": 5034.322858624644,
"y": -8853.749443362783,
"z": 1751.6938551264584,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 5`] = `
Vector3 {
"x": 5029.393815983156,
"y": -8797.410228168032,
"z": 132.187106929523,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 6`] = `
Vector3 {
"x": 4905.510413292816,
"y": -7381.416455973404,
"z": 169.1161662197635,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 7`] = `
Vector3 {
"x": 4781.627010602477,
"y": -5965.4226837787755,
"z": 206.045225510004,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 8`] = `
Vector3 {
"x": 4781.627010602477,
"y": -5965.4226837787755,
"z": 206.045225510004,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 9`] = `
Vector3 {
"x": 4704.992717868391,
"y": -5089.488709643054,
"z": 1250.7720344676763,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 10`] = `
Vector3 {
"x": 4628.358425134305,
"y": -4213.554735507332,
"z": 2295.4988434253487,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 11`] = `
Vector3 {
"x": 4628.358425134305,
"y": -4213.554735507332,
"z": 2295.4988434253487,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 12`] = `
Vector3 {
"x": 3442.5773443702283,
"y": -4281.794751914184,
"z": 1282.712218082731,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 13`] = `
Vector3 {
"x": 2256.79626360615,
"y": -4350.034768321036,
"z": 269.9255927401132,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 14`] = `
Vector3 {
"x": 2261.752779030607,
"y": -4406.687998862022,
"z": 1898.4589127575264,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 15`] = `
Vector3 {
"x": 2266.709294455064,
"y": -4463.341229403009,
"z": 3526.992232774939,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 16`] = `
Vector3 {
"x": 3450.140391034055,
"y": -4368.240770849953,
"z": 3767.6582816246537,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 17`] = `
Vector3 {
"x": 4633.571487613046,
"y": -4273.140312296899,
"z": 4008.3243304743673,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 18`] = `
Vector3 {
"x": 4633.571487613046,
"y": -4273.140312296899,
"z": 4008.324330474368,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 19`] = `
Vector3 {
"x": 4702.509796382463,
"y": -5061.108787195242,
"z": 3851.2457381799186,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 三线段连接点拖拽 20`] = `
Vector3 {
"x": 4771.44810515188,
"y": -5849.077262093586,
"z": 3694.167145885469,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 1`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 2`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -1270.3243319424719,
"z": -1756.964229759154,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 3`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2540.6486638849437,
"z": -1754.5919838318846,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 4`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2593.58003880636,
"z": 1763.9937876113904,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 5`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2646.5114137277756,
"z": 5282.579559054666,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 6`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -1323.2557068638878,
"z": 5229.64818413325,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 7`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": 5176.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 8`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": 5176.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 9`] = `
Vector3 {
"x": 152.18826649869084,
"y": 0,
"z": 3926.7168092118336,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 10`] = `
Vector3 {
"x": -1452.394394942868,
"y": 0,
"z": 2676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 11`] = `
Vector3 {
"x": -1452.394394942868,
"y": 0,
"z": 458.6901667627053,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 12`] = `
Vector3 {
"x": -1452.394394942868,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 13`] = `
Vector3 {
"x": 152.1882664986906,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 中间点拖拽 14`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 1`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 2`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2540.6486638849437,
"z": -1754.5919838318846,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 3`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2646.5114137277756,
"z": 2782.5795590546654,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 4`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": 2676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 5`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": 2676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 6`] = `
Vector3 {
"x": -3952.394394942868,
"y": 0,
"z": 2676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 7`] = `
Vector3 {
"x": -3952.394394942868,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 二线段拉伸 8`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 1`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 2`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -1270.3243319424719,
"z": -1756.964229759154,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 3`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2540.6486638849437,
"z": -1754.5919838318846,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 4`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2593.58003880636,
"z": 513.9937876113904,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 5`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -2646.5114137277756,
"z": 2782.5795590546654,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 6`] = `
Vector3 {
"x": 1756.7709279402495,
"y": -1323.2557068638878,
"z": 4229.64818413325,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 7`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": 5676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 8`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": 5676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 9`] = `
Vector3 {
"x": 152.18826649869084,
"y": 0,
"z": 4176.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 10`] = `
Vector3 {
"x": -1452.394394942868,
"y": 0,
"z": 2676.716809211834,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 11`] = `
Vector3 {
"x": -1452.394394942868,
"y": 0,
"z": 458.6901667627053,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 12`] = `
Vector3 {
"x": -1452.394394942868,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 13`] = `
Vector3 {
"x": 152.1882664986906,
"y": 0,
"z": -1759.3364756864237,
}
`;
exports[`三维扫掠夹点拉伸及拖拽 连接点拖拽 14`] = `
Vector3 {
"x": 1756.7709279402495,
"y": 0,
"z": -1759.3364756864237,
}
`;

@ -1,123 +1,123 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`顶线分段测试 不闭合多补圆弧 1`] = `7527.309534097063`; exports[`顶线分段测试 三维顶线 1`] = `2721.682828800552`;
exports[`顶线分段测试 不闭合多补圆弧 2`] = `181.54910804222436`; exports[`顶线分段测试 三维顶线 2`] = `4642.836785695566`;
exports[`顶线分段测试 不闭合多补圆弧 3`] = `7972.744263135363`; exports[`顶线分段测试 三维顶线 3`] = `2721.76916405858`;
exports[`顶线分段测试 不闭合多补圆弧 4`] = `175.5593866359881`; exports[`顶线分段测试 三维顶线 4`] = `3390.2858230567535`;
exports[`顶线分段测试 不闭合多补圆弧 5`] = `9102.21522360141`; exports[`顶线分段测试 三维顶线 5`] = `4647.778784583921`;
exports[`顶线分段测试 不闭合多补圆弧 6`] = `174.8880833875153`; exports[`顶线分段测试 三维顶线 6`] = `3390.392564825428`;
exports[`顶线分段测试 不闭合多补圆弧 7`] = `9850.281806459629`; exports[`顶线分段测试 不闭合多补圆弧 1`] = `8332.345474217764`;
exports[`顶线分段测试 不闭合多补圆弧 8`] = `167.5163609665956`; exports[`顶线分段测试 不闭合多补圆弧 2`] = `9260.51515812123`;
exports[`顶线分段测试 不闭合多补圆弧 9`] = `9201.576517258296`; exports[`顶线分段测试 不闭合多补圆弧 3`] = `10060.210786043295`;
exports[`顶线分段测试 不闭合多补圆弧 10`] = `8466.391158009821`; exports[`顶线分段测试 不闭合多补圆弧 4`] = `10635.124906803252`;
exports[`顶线分段测试 不闭合多补圆弧 11`] = `13771.549281343903`; exports[`顶线分段测试 不闭合多补圆弧 5`] = `9520.046158289355`;
exports[`顶线分段测试 不闭合多补圆弧 12`] = `8903.394215503084`; exports[`顶线分段测试 不闭合多补圆弧 6`] = `8786.945272592342`;
exports[`顶线分段测试 不闭合多补圆弧 7`] = `13951.062223956982`;
exports[`顶线分段测试 不闭合多补圆弧 8`] = `8598.01492440969`;
exports[`顶线分段测试 不闭合直线 1`] = `1107.864406779661`; exports[`顶线分段测试 不闭合直线 1`] = `1107.864406779661`;
exports[`顶线分段测试 不闭合直线 2`] = `1703.186440677966`; exports[`顶线分段测试 不闭合直线 2`] = `1703.186440677966`;
exports[`顶线分段测试 不闭合直线 3`] = `877.3559322033899`; exports[`顶线分段测试 不闭合直线 3`] = `877.35593220339`;
exports[`顶线分段测试 不闭合直线 4`] = `1204.7457627118647`; exports[`顶线分段测试 不闭合直线 4`] = `1204.7457627118647`;
exports[`顶线分段测试 不闭合直线 5`] = `760.6101694915253`; exports[`顶线分段测试 不闭合直线 5`] = `760.6101694915254`;
exports[`顶线分段测试 不闭合直线 6`] = `1341.5593220338988`; exports[`顶线分段测试 不闭合直线 6`] = `1341.5593220338988`;
exports[`顶线分段测试 不闭合直线 7`] = `1127.7966101694917`; exports[`顶线分段测试 不闭合直线 7`] = `1127.7966101694915`;
exports[`顶线分段测试 不闭合直线圆弧 1`] = `2149.542819791226`;
exports[`顶线分段测试 不闭合直线圆弧 2`] = `3886.6189286714807`;
exports[`顶线分段测试 不闭合直线圆弧 3`] = `4288.29067911474`; exports[`顶线分段测试 不闭合直线圆弧 1`] = `2149.0765416496856`;
exports[`顶线分段测试 不闭合直线圆弧 4`] = `2721.960193789361`; exports[`顶线分段测试 不闭合直线圆弧 2`] = `3885.0721054475634`;
exports[`顶线分段测试 不闭合直线圆弧 5`] = `2351.778679840207`; exports[`顶线分段测试 不闭合直线圆弧 3`] = `4290.352436993804`;
exports[`顶线分段测试 不闭合直线圆弧 6`] = `4128.24578371541`; exports[`顶线分段测试 不闭合直线圆弧 4`] = `2720.5813805765733`;
exports[`顶线分段测试 不闭合直线圆弧2 1`] = `4393.076886867966`; exports[`顶线分段测试 不闭合直线圆弧 5`] = `2351.778679840056`;
exports[`顶线分段测试 不闭合直线圆弧2 2`] = `6.566024064602179`; exports[`顶线分段测试 不闭合直线圆弧 6`] = `4128.245783715364`;
exports[`顶线分段测试 不闭合直线圆弧2 3`] = `8562.229412244687`; exports[`顶线分段测试 不闭合直线圆弧2 1`] = `4396.01934675645`;
exports[`顶线分段测试 不闭合直线圆弧2 4`] = `7775.24228697155`; exports[`顶线分段测试 不闭合直线圆弧2 2`] = `8566.964954296875`;
exports[`顶线分段测试 不闭合直线圆弧2 5`] = `7158.345287787588`; exports[`顶线分段测试 不闭合直线圆弧2 3`] = `7771.3839398258315`;
exports[`顶线分段测试 不闭合直线圆弧2 6`] = `11250.987271676096`; exports[`顶线分段测试 不闭合直线圆弧2 4`] = `7152.883616395713`;
exports[`顶线分段测试 闭合圆弧 1`] = `183.06306067444856`; exports[`顶线分段测试 不闭合直线圆弧2 5`] = `11117.77639252228`;
exports[`顶线分段测试 闭合圆弧 2`] = `5822.513453880229`; exports[`顶线分段测试 闭合圆弧 1`] = `6933.9381077667895`;
exports[`顶线分段测试 闭合圆弧 3`] = `6427.174944008036`; exports[`顶线分段测试 闭合圆弧 2`] = `6428.240330201794`;
exports[`顶线分段测试 闭合圆弧 4`] = `9954.439545178504`; exports[`顶线分段测试 闭合圆弧 3`] = `9956.600010830436`;
exports[`顶线分段测试 闭合圆弧 5`] = `5190.973862843558`; exports[`顶线分段测试 闭合圆弧 4`] = `5191.714511479803`;
exports[`顶线分段测试 闭合圆弧 6`] = `7730.577675302795`; exports[`顶线分段测试 闭合圆弧 5`] = `7730.598935634274`;
exports[`顶线分段测试 闭合圆弧 7`] = `14243.520190228797`; exports[`顶线分段测试 闭合圆弧 6`] = `14243.548735716871`;
exports[`顶线分段测试 闭合圆弧 8`] = `11360.440190078047`; exports[`顶线分段测试 闭合圆弧 7`] = `11361.148377723342`;
exports[`顶线分段测试 闭合圆弧 9`] = `4713.85413305274`; exports[`顶线分段测试 闭合圆弧 8`] = `5816.095365378227`;
exports[`顶线分段测试 闭合直线 1`] = `1411.8807330899142`; exports[`顶线分段测试 闭合直线 1`] = `2152.655017660517`;
exports[`顶线分段测试 闭合直线 2`] = `2152.655017660556`; exports[`顶线分段测试 闭合直线 2`] = `1157.9339062625752`;
exports[`顶线分段测试 闭合直线 3`] = `1157.9339062625943`; exports[`顶线分段测试 闭合直线 3`] = `1049.3737454027569`;
exports[`顶线分段测试 闭合直线 4`] = `1049.373745402737`; exports[`顶线分段测试 闭合直线 4`] = `1007.793343552591`;
exports[`顶线分段测试 闭合直线 5`] = `1007.7933435525692`; exports[`顶线分段测试 闭合直线 5`] = `1867.3971281882955`;
exports[`顶线分段测试 闭合直线 6`] = `1867.3971281882991`; exports[`顶线分段测试 闭合直线 6`] = `711.6950394345738`;
exports[`顶线分段测试 闭合直线 7`] = `711.6950394345639`; exports[`顶线分段测试 闭合直线 7`] = `1109.709597624015`;
exports[`顶线分段测试 闭合直线 8`] = `1109.7095976240196`; exports[`顶线分段测试 闭合直线 8`] = `1099.4488714706827`;
exports[`顶线分段测试 闭合直线 9`] = `1099.4488714706863`; exports[`顶线分段测试 闭合直线 9`] = `1411.880733089909`;
exports[`顶线分段测试 闭合直线2 1`] = `2378.824808973823`; exports[`顶线分段测试 闭合直线2 1`] = `1773.6483926638061`;
exports[`顶线分段测试 闭合直线2 2`] = `1773.6483926638098`; exports[`顶线分段测试 闭合直线2 2`] = `1327.031499455764`;
exports[`顶线分段测试 闭合直线2 3`] = `1327.0314994557618`; exports[`顶线分段测试 闭合直线2 3`] = `1593.058941817248`;
exports[`顶线分段测试 闭合直线2 4`] = `1593.058941817248`; exports[`顶线分段测试 闭合直线2 4`] = `1234.7942063629357`;
exports[`顶线分段测试 闭合直线2 5`] = `1234.7942063629366`; exports[`顶线分段测试 闭合直线2 5`] = `1657.0432133817048`;
exports[`顶线分段测试 闭合直线2 6`] = `1657.0432133817048`; exports[`顶线分段测试 闭合直线2 6`] = `1812.9802996395224`;
exports[`顶线分段测试 闭合直线2 7`] = `1812.9802996395224`; exports[`顶线分段测试 闭合直线2 7`] = `1366.7470210563024`;
exports[`顶线分段测试 闭合直线2 8`] = `1366.7470210563024`; exports[`顶线分段测试 闭合直线2 8`] = `2149.6670549035985`;
exports[`顶线分段测试 闭合直线2 9`] = `2149.6670549035985`; exports[`顶线分段测试 闭合直线2 9`] = `1980.1205315844518`;
exports[`顶线分段测试 闭合直线2 10`] = `1980.1205315844518`; exports[`顶线分段测试 闭合直线2 10`] = `1613.0589418172476`;
exports[`顶线分段测试 闭合直线2 11`] = `1613.0589418172485`; exports[`顶线分段测试 闭合直线2 11`] = `1665.8400676945942`;
exports[`顶线分段测试 闭合直线2 12`] = `1665.8400676945942`; exports[`顶线分段测试 闭合直线2 12`] = `2378.8248089738245`;

@ -8,7 +8,7 @@ import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { JigUtils } from "../../Editor/JigUtils"; import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { isParallelTo, YAxis } from "../../Geometry/GeUtils"; import { YAxis, isParallelTo } from "../../Geometry/GeUtils";
import { PlaneExt } from "../../Geometry/Plane"; import { PlaneExt } from "../../Geometry/Plane";
import { ExtrudeApplyContour, SelectExtrudeContours } from "../DrawBoard/DrawSpecialShapeBoardTool"; import { ExtrudeApplyContour, SelectExtrudeContours } from "../DrawBoard/DrawSpecialShapeBoardTool";
@ -187,8 +187,7 @@ export class CuttingByRectFace extends CuttingByFace
{ {
let rec = new Polyline(); let rec = new Polyline();
rec.RectangleFrom2Pt(rectRes.Point1UCS, rectRes.Point2UCS); rec.RectangleFrom2Pt(rectRes.Point1UCS, rectRes.Point2UCS);
rec.Position = new Vector3(0, 0, rectRes.Point1UCS.z); rec.ApplyMatrix(rectRes.UCS);
rec.ApplyMatrix(app.Editor.UCSMatrix);
let map = new Map(); let map = new Map();
map.set(rec, []); map.set(rec, []);

@ -271,8 +271,7 @@ export class RectLinearCutting extends LinearCutting
{ {
let rec = new Polyline(); let rec = new Polyline();
rec.RectangleFrom2Pt(rectRes.Point1UCS, rectRes.Point2UCS); rec.RectangleFrom2Pt(rectRes.Point1UCS, rectRes.Point2UCS);
rec.Position = new Vector3(0, 0, rectRes.Point1UCS.z); rec.ApplyMatrix(rectRes.UCS);
rec.ApplyMatrix(app.Editor.UCSMatrix);
let pts = rec.GetStretchPoints(); let pts = rec.GetStretchPoints();
pts.push(pts[0]); pts.push(pts[0]);

@ -3,6 +3,7 @@ import { app } from "../ApplicationServices/Application";
import { LogType } from "../Common/Log"; import { LogType } from "../Common/Log";
import { Command } from "../Editor/CommandMachine"; import { Command } from "../Editor/CommandMachine";
import { PromptPointResult, PromptStatus } from "../Editor/PromptResult"; import { PromptPointResult, PromptStatus } from "../Editor/PromptResult";
import { GetPointUCS } from "../Editor/UCSRAII";
import { UCSPsotion } from "../Editor/UCSServices"; import { UCSPsotion } from "../Editor/UCSServices";
import { equalv3 } from "../Geometry/GeUtils"; import { equalv3 } from "../Geometry/GeUtils";
@ -13,6 +14,7 @@ export class CustomUcs implements Command
let p1Res = await app.Editor.GetPoint( let p1Res = await app.Editor.GetPoint(
{ {
Msg: "请点击坐标原点或", Msg: "请点击坐标原点或",
Raycast: true,
KeyWordList: [ KeyWordList: [
{ key: "W", msg: "世界" }, { key: "W", msg: "世界" },
{ key: "O", msg: "图标显示在原点" }, { key: "O", msg: "图标显示在原点" },
@ -44,15 +46,17 @@ export class CustomUcs implements Command
} }
if (p1Res.Status !== PromptStatus.OK) return; if (p1Res.Status !== PromptStatus.OK) return;
let mat = app.Editor.UCSMatrix; let oldUcs = app.Editor.UCSMatrix;
let oldMat = mat.clone(); let ucsMtx = GetPointUCS(p1Res);
mat.setPosition(p1Res.Point); if (!ucsMtx)
app.Editor.UCSMatrix = mat; ucsMtx = app.Editor.UCSMatrix.setPosition(p1Res.Point);
app.Editor.UCSMatrix = ucsMtx;
let xv: Vector3, yv: Vector3, zv: Vector3; let xv: Vector3, yv: Vector3, zv: Vector3;
while (true) while (true)
{ {
let xRes = await app.Editor.GetPoint({ Msg: "请点击X轴方向(空格仅修改基点):", BasePoint: p1Res.Point, AllowDrawRubberBand: true, AllowNone: true }); let xRes = await app.Editor.GetPoint({ Msg: "请点击X轴方向(空格接受当前UCS):", BasePoint: p1Res.Point, AllowDrawRubberBand: true, AllowNone: true });
if (xRes.Status === PromptStatus.None) if (xRes.Status === PromptStatus.None)
{ {
@ -60,7 +64,7 @@ export class CustomUcs implements Command
} }
else if (xRes.Status !== PromptStatus.OK) else if (xRes.Status !== PromptStatus.OK)
{ {
app.Editor.UCSMatrix = oldMat; app.Editor.UCSMatrix = oldUcs;
return; return;
} }
else else
@ -72,10 +76,10 @@ export class CustomUcs implements Command
else else
{ {
xv = xRes.Point.sub(p1Res.Point).normalize(); xv = xRes.Point.sub(p1Res.Point).normalize();
zv = new Vector3().setFromMatrixColumn(mat, 2); zv = new Vector3().setFromMatrixColumn(ucsMtx, 2);
yv = zv.clone().cross(xv); yv = zv.clone().cross(xv);
this.UpdateUCS(mat, xv, yv, zv, p1Res); this.UpdateUCS(ucsMtx, xv, yv, zv, p1Res);
break; break;
} }
} }
@ -100,13 +104,13 @@ export class CustomUcs implements Command
yv = yRes.Point.sub(p1Res.Point).normalize(); yv = yRes.Point.sub(p1Res.Point).normalize();
zv = xv.clone().cross(yv); zv = xv.clone().cross(yv);
yv = zv.clone().cross(xv); yv = zv.clone().cross(xv);
this.UpdateUCS(mat, xv, yv, zv, p1Res); this.UpdateUCS(ucsMtx, xv, yv, zv, p1Res);
break; break;
} }
} }
else else
{ {
app.Editor.UCSMatrix = oldMat; app.Editor.UCSMatrix = oldUcs;
return; return;
} }
} }

@ -3,15 +3,19 @@ import { Arc } from '../DatabaseServices/Entity/Arc';
import { Command } from '../Editor/CommandMachine'; import { Command } from '../Editor/CommandMachine';
import { JigUtils } from '../Editor/JigUtils'; import { JigUtils } from '../Editor/JigUtils';
import { PromptStatus } from '../Editor/PromptResult'; import { PromptStatus } from '../Editor/PromptResult';
import { UCSUtils } from '../Editor/UCSRAII';
import { equalv3 } from '../Geometry/GeUtils'; import { equalv3 } from '../Geometry/GeUtils';
export class DrawArc implements Command export class DrawArc implements Command
{ {
async exec() async exec()
{ {
let ptRes = await app.Editor.GetPoint({ Msg: "请输入第一个点:" }); let ptRes = await app.Editor.GetPoint({ Msg: "请输入第一个点:", Raycast: true });
if (ptRes.Status != PromptStatus.OK) if (ptRes.Status != PromptStatus.OK)
return; return;
UCSUtils.SetUCSFromPointRes(ptRes);
let pt1 = ptRes.Point; let pt1 = ptRes.Point;
let ptRes2 = await app.Editor.GetPoint({ Msg: "请输入第二个点:", BasePoint: pt1, AllowDrawRubberBand: true }); let ptRes2 = await app.Editor.GetPoint({ Msg: "请输入第二个点:", BasePoint: pt1, AllowDrawRubberBand: true });
if (ptRes2.Status != PromptStatus.OK) if (ptRes2.Status != PromptStatus.OK)
@ -41,6 +45,5 @@ export class DrawArc implements Command
updateArc(ptRes3.Point); updateArc(ptRes3.Point);
app.LayoutTool.AppendDatabaseSpace(arc); app.LayoutTool.AppendDatabaseSpace(arc);
} }
JigUtils.End();
} }
} }

@ -12,6 +12,7 @@ import { Polyline } from '../DatabaseServices/Entity/Polyline';
import { Command } from '../Editor/CommandMachine'; import { Command } from '../Editor/CommandMachine';
import { JigUtils } from '../Editor/JigUtils'; import { JigUtils } from '../Editor/JigUtils';
import { PromptStatus } from '../Editor/PromptResult'; import { PromptStatus } from '../Editor/PromptResult';
import { UCSUtils } from '../Editor/UCSRAII';
import { angle, midPoint, polar } from '../Geometry/GeUtils'; import { angle, midPoint, polar } from '../Geometry/GeUtils';
import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectOption } from '../GraphicsSystem/IntersectWith';
export class DrawCircle implements Command export class DrawCircle implements Command
@ -20,8 +21,10 @@ export class DrawCircle implements Command
{ {
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
Msg: "指定圆的圆心", Msg: "指定圆的圆心",
KeyWordList: [{ key: "3P", msg: "三点" }, { key: "2P", msg: "二点" }, { key: "T", msg: "切点、切点、半径" }, { key: "3T", msg: "三角形内切圆" }] KeyWordList: [{ key: "3P", msg: "三点" }, { key: "2P", msg: "二点" }, { key: "T", msg: "切点、切点、半径" }, { key: "3T", msg: "三角形内切圆" }],
Raycast: true,
}); });
switch (ptRes.Status) switch (ptRes.Status)
{ {
case PromptStatus.Cancel: case PromptStatus.Cancel:
@ -47,7 +50,11 @@ export class DrawCircle implements Command
} }
break; break;
case PromptStatus.OK: case PromptStatus.OK:
await this.DrawCircleUseRadious(ptRes.Point); //圆心半径画圆 {
UCSUtils.SetUCSFromPointRes(ptRes);
await this.DrawCircleUseRadious(ptRes.Point); //圆心半径画圆
}
break; break;
default: default:
break; break;
@ -99,9 +106,12 @@ export class DrawCircle implements Command
} }
async DrawCicleUseThreePoint() async DrawCicleUseThreePoint()
{ {
let ptRes1 = await app.Editor.GetPoint({ Msg: "指定圆上第一个点:" }); let ptRes1 = await app.Editor.GetPoint({ Msg: "指定圆上第一个点:", Raycast: true });
if (ptRes1.Status != PromptStatus.OK) if (ptRes1.Status != PromptStatus.OK)
return; return;
UCSUtils.SetUCSFromPointRes(ptRes1);
let cir = new Circle(); let cir = new Circle();
cir.ApplyMatrix(app.Editor.UCSMatrix); cir.ApplyMatrix(app.Editor.UCSMatrix);
let ar = new Arc(); let ar = new Arc();

@ -1,4 +1,3 @@
import { Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { EntityUpdateWrap } from "../../Common/EntityUpdateWrap"; import { EntityUpdateWrap } from "../../Common/EntityUpdateWrap";
import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight"; import { RectAreaLight } from "../../DatabaseServices/Lights/RectAreaLight";
@ -7,7 +6,6 @@ import { JigUtils } from "../../Editor/JigUtils";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { userConfig } from "../../Editor/UserConfig"; import { userConfig } from "../../Editor/UserConfig";
import { midPoint } from "../../Geometry/GeUtils"; import { midPoint } from "../../Geometry/GeUtils";
import { Orbit } from "../../Geometry/Orbit";
import { BoardModalType } from "../../UI/Components/Board/BoardModalType"; import { BoardModalType } from "../../UI/Components/Board/BoardModalType";
import { ModalState } from "../../UI/Components/Modal/ModalInterface"; import { ModalState } from "../../UI/Components/Modal/ModalInterface";
import { LightConfigModel } from "../../UI/Store/RightPanelStore/LightConfigModel"; import { LightConfigModel } from "../../UI/Store/RightPanelStore/LightConfigModel";
@ -17,36 +15,7 @@ export class DrawRectAreaLight implements Command
{ {
async exec() async exec()
{ {
let ptRes = await app.Editor.GetPoint({ let rectRes = await app.Editor.GetRectPoint({ Msg: "选择矩形光范围:" });
Msg: "选择矩形光范围:",
Raycast: true
});
if (ptRes.Status !== PromptStatus.OK) return;
let ucsMtx: Matrix4;
let bakMtx: Matrix4;
if (ptRes.intersection?.face?.normal)
{
let i = ptRes.intersection;
let normal = i.face.normal.clone().transformDirection(i.object.matrix).negate();
let x = new Vector3;
let y = new Vector3;
Orbit.ComputUpDirection(normal, y, x);
let p = ptRes.Point;
p.sub(normal.clone().multiplyScalar(5));
ptRes.Point = p;
let mtx = new Matrix4().makeBasis(x, y, normal).setPosition(p);
bakMtx = app.Editor.UCSMatrix;
ucsMtx = mtx;
app.Editor.UCSMatrix = mtx;
}
let rectRes = await app.Editor.GetRectPoint({ BasePoint: ptRes.Point, Msg: "选择矩形光范围:" });
if (bakMtx) app.Editor.UCSMatrix = bakMtx;
if (rectRes.Status !== PromptStatus.OK) return; if (rectRes.Status !== PromptStatus.OK) return;
let light = JigUtils.Draw(new RectAreaLight()); let light = JigUtils.Draw(new RectAreaLight());
@ -55,7 +24,7 @@ export class DrawRectAreaLight implements Command
{ {
light.Width = Math.abs(rectRes.Width); light.Width = Math.abs(rectRes.Width);
light.Height = Math.abs(rectRes.Height); light.Height = Math.abs(rectRes.Height);
light.ApplyMatrix(ucsMtx ?? app.Editor.UCSMatrix); light.ApplyMatrix(rectRes.UCS);
light.Position = midPoint(rectRes.Point1WCS, rectRes.Point2WCS); light.Position = midPoint(rectRes.Point1WCS, rectRes.Point2WCS);
}); });

@ -9,16 +9,19 @@ import { JigUtils } from '../Editor/JigUtils';
import { ObjectSnapMode } from '../Editor/ObjectSnapMode'; import { ObjectSnapMode } from '../Editor/ObjectSnapMode';
import { PromptStatus } from '../Editor/PromptResult'; import { PromptStatus } from '../Editor/PromptResult';
import { SelectPick } from '../Editor/SelectPick'; import { SelectPick } from '../Editor/SelectPick';
import { UCSUtils } from '../Editor/UCSRAII';
import { equalv3, ZeroVec } from '../Geometry/GeUtils'; import { equalv3, ZeroVec } from '../Geometry/GeUtils';
export class DrawLine implements Command export class DrawLine implements Command
{ {
async exec() async exec()
{ {
let ptRes = await app.Editor.GetPoint({ Msg: "请输入第一个点:" }); let ptRes = await app.Editor.GetPoint({ Msg: "请输入第一个点:", Raycast: true });
if (ptRes.Status !== PromptStatus.OK) if (ptRes.Status !== PromptStatus.OK)
return; return;
UCSUtils.SetUCSFromPointRes(ptRes);
let ptLast = ptRes.Point; let ptLast = ptRes.Point;
let isTan = ptRes.SnaoMode === ObjectSnapMode.Tan; let isTan = ptRes.SnaoMode === ObjectSnapMode.Tan;
let cir: Circle | Arc; let cir: Circle | Arc;
@ -76,6 +79,7 @@ export class DrawLine implements Command
AllowDrawRubberBand: true, AllowDrawRubberBand: true,
AllowNone: true, AllowNone: true,
SupportSnapPoints: pts, SupportSnapPoints: pts,
Raycast: true,
KeyWordList: [ KeyWordList: [
{ msg: "放弃", key: "U" }, { msg: "放弃", key: "U" },
{ msg: "闭合", key: "C" }, { msg: "闭合", key: "C" },
@ -129,7 +133,10 @@ export class Command_DrawXLine implements Command
{ {
async exec() async exec()
{ {
let ptRes = await app.Editor.GetPoint({ Msg: "请输入第一个点:" }); let ptRes = await app.Editor.GetPoint({
Msg: "请输入第一个点:",
Raycast: true,
});
if (ptRes.Status !== PromptStatus.OK) if (ptRes.Status !== PromptStatus.OK)
return; return;
@ -151,7 +158,9 @@ export class Command_DrawXLine implements Command
let pt2Res = await app.Editor.GetPoint({ let pt2Res = await app.Editor.GetPoint({
BasePoint: p1, BasePoint: p1,
Msg: "点击构造线的方向:", Callback: UpdateLine Msg: "点击构造线的方向:",
Raycast: true,
Callback: UpdateLine
}); });
if (pt2Res.Status !== PromptStatus.OK) if (pt2Res.Status !== PromptStatus.OK)
return; return;

@ -2,11 +2,13 @@ import hotkeys from 'hotkeys-js-ext';
import { Vector2, Vector3 } from 'three'; import { Vector2, Vector3 } from 'three';
import { app } from '../ApplicationServices/Application'; import { app } from '../ApplicationServices/Application';
import { getCirAngleByChordAndTangent } from '../Common/CurveUtils'; import { getCirAngleByChordAndTangent } from '../Common/CurveUtils';
import { UpdateDraw } from '../Common/Status';
import { Polyline } from '../DatabaseServices/Entity/Polyline'; import { Polyline } from '../DatabaseServices/Entity/Polyline';
import { JigUtils } from '../Editor/JigUtils'; import { JigUtils } from '../Editor/JigUtils';
import { GetPointPrompt } from "../Editor/PromptOptions"; import { GetPointPrompt } from "../Editor/PromptOptions";
import { PromptStatus } from '../Editor/PromptResult'; import { PromptStatus } from '../Editor/PromptResult';
import { AsVector2, AsVector3, equalv3, isParallelTo, XAxis, ZeroVec } from '../Geometry/GeUtils'; import { UCSUtils } from '../Editor/UCSRAII';
import { AsVector2, AsVector3, XAxis, ZeroVec, equalv3, isParallelTo } from '../Geometry/GeUtils';
enum PolylineModel enum PolylineModel
{ {
@ -22,7 +24,6 @@ export class DrawPolyline
this.model = PolylineModel.Line; this.model = PolylineModel.Line;
let pl = new Polyline(); let pl = new Polyline();
pl.ApplyMatrix(app.Editor.UCSMatrix);
app.LayoutTool.AppendDatabaseSpace(pl); app.LayoutTool.AppendDatabaseSpace(pl);
let plJig = JigUtils.Draw(pl); let plJig = JigUtils.Draw(pl);
@ -30,11 +31,20 @@ export class DrawPolyline
let Callback = (p: Vector3) => let Callback = (p: Vector3) =>
this.UpdatePoint(plJig, p); this.UpdatePoint(plJig, p);
let firstOps: GetPointPrompt = { Msg: "请输入第一个点:", Callback, AllowNone: true }; let firstOps: GetPointPrompt = {
Msg: "请输入第一个点:",
Callback,
AllowNone: true,
NotSnapZ: true,
};
let keywords = [{ msg: "圆弧", key: "A" }, { msg: "直线", key: "L" }, { msg: "放弃", key: "U" }]; let keywords = [{ msg: "圆弧", key: "A" }, { msg: "直线", key: "L" }, { msg: "放弃", key: "U" }];
let keywords2 = keywords.concat([{ msg: "闭合", key: "C" }]); let keywords2 = keywords.concat([{ msg: "闭合", key: "C" }]);
let nextOps: GetPointPrompt = { Msg: "请点击下一个点或", Callback, AllowNone: true }; let nextOps: GetPointPrompt = {
Msg: "请点击下一个点或",
Callback,
AllowNone: true,
NotSnapZ: true,
};
const TempUndo = () => const TempUndo = () =>
{ {
@ -59,11 +69,22 @@ export class DrawPolyline
nextOps.KeyWordList = keywords; nextOps.KeyWordList = keywords;
} }
ops.Raycast = true;
plJig.AddVertexAt(plJig.NumberOfVertices, new Vector2()); plJig.AddVertexAt(plJig.NumberOfVertices, new Vector2());
let p = await app.Editor.GetPoint(ops); let p = await app.Editor.GetPoint(ops);
if (p.Status === PromptStatus.OK) if (p.Status === PromptStatus.OK)
{ {
if (ops === firstOps)
{
let ucs = UCSUtils.SetUCSFromPointRes(p) ?? app.Editor.UCSMatrix;
pl.OCS = ucs;
plJig.OCS = ucs;
pl.Update(UpdateDraw.Matrix);
plJig.Update(UpdateDraw.Matrix);
}
//避免直接画出0长度的多段线段 //避免直接画出0长度的多段线段
if (ops === firstOps || !equalv3(p.Point, pl.EndPoint)) if (ops === firstOps || !equalv3(p.Point, pl.EndPoint))
{ {

@ -8,14 +8,14 @@ export class DrawRect implements Command
async exec() async exec()
{ {
let rectRes = await app.Editor.GetRectPoint(); let rectRes = await app.Editor.GetRectPoint({});
if (rectRes.Status === PromptStatus.OK) if (rectRes.Status === PromptStatus.OK)
{ {
let rec = new Polyline(); let rec = new Polyline();
rec.RectangleFrom2Pt(rectRes.Point1UCS, rectRes.Point2UCS); rec.RectangleFrom2Pt(rectRes.Point1UCS, rectRes.Point2UCS);
rec.Position = new Vector3(0, 0, rectRes.Point1UCS.z); rec.Position = new Vector3(0, 0, rectRes.Point1UCS.z);
rec.ApplyMatrix(app.Editor.UCSMatrix); rec.ApplyMatrix(rectRes.UCS);
app.LayoutTool.AppendDatabaseSpace(rec); app.LayoutTool.AppendDatabaseSpace(rec);
} }
} }

@ -1,16 +1,17 @@
import { Scene } from "three";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { curveLinkGroup } from "../Common/CurveUtils"; import { curveLinkGroup } from "../Common/CurveUtils";
import { DisposeThreeObj } from "../Common/Dispose";
import { Arc } from "../DatabaseServices/Entity/Arc"; import { Arc } from "../DatabaseServices/Entity/Arc";
import { Board } from "../DatabaseServices/Entity/Board"; import { Board } from "../DatabaseServices/Entity/Board";
import { Curve } from "../DatabaseServices/Entity/Curve"; import { Curve } from "../DatabaseServices/Entity/Curve";
import { Line } from "../DatabaseServices/Entity/Line"; import { Line } from "../DatabaseServices/Entity/Line";
import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { HardwareTopline } from "../DatabaseServices/Hardware/HardwareTopline";
import { JigUtils } from "../Editor/JigUtils"; import { JigUtils } from "../Editor/JigUtils";
import { PromptStatus } from "../Editor/PromptResult"; import { PromptStatus } from "../Editor/PromptResult";
import { equalv3 } from "../Geometry/GeUtils";
import { SurroundOutlineParse } from "../Geometry/SpaceParse/SurroundOutlineParse"; import { SurroundOutlineParse } from "../Geometry/SpaceParse/SurroundOutlineParse";
import { HardwareTopline } from "../DatabaseServices/Hardware/HardwareTopline";
import { Scene } from "three";
import { DisposeThreeObj } from "../Common/Dispose";
/**构建顶线 */ /**构建顶线 */
export async function buildTopline(outline: Polyline, name: string) export async function buildTopline(outline: Polyline, name: string)
@ -81,8 +82,13 @@ async function draw(outline: Polyline, cus: Curve[])
let group = curveLinkGroup(cus); let group = curveLinkGroup(cus);
for (let cus of group) for (let cus of group)
{ {
let path = Polyline.Combine(cus); let curves: Curve | Curve[];
let sweepSolid = new HardwareTopline(outline, path); if (cus.find((v) => cus.some(c => !equalv3(v.Normal, c.Normal))))
curves = cus.map((v) => v.Clone());
else
curves = Polyline.Combine(cus);
let sweepSolid = new HardwareTopline(outline, curves);
JigUtils.Draw(sweepSolid); JigUtils.Draw(sweepSolid);
result.push(sweepSolid); result.push(sweepSolid);
} }

@ -1,5 +1,5 @@
import { Intent } from "@blueprintjs/core"; import { Intent } from "@blueprintjs/core";
import { Vector3 } from "three"; import { Matrix4, Vector3 } from "three";
import { app } from "../ApplicationServices/Application"; import { app } from "../ApplicationServices/Application";
import { Sleep } from "../Common/Sleep"; import { Sleep } from "../Common/Sleep";
import { Hole } from "../DatabaseServices/3DSolid/Hole"; import { Hole } from "../DatabaseServices/3DSolid/Hole";
@ -23,7 +23,7 @@ import { Viewport4ConfigModal, Viewport4ConfigStore } from "./ViewortConfig/View
import { ViewportConfigModal, ViewportConfigStore } from "./ViewortConfig/ViewportConfig"; import { ViewportConfigModal, ViewportConfigStore } from "./ViewortConfig/ViewportConfig";
import { HideEntityText } from "./Viewport/OneKeyLayout"; import { HideEntityText } from "./Viewport/OneKeyLayout";
async function GetViewportInfo(): Promise<{ p1: Vector3; p2: Vector3; ens: Entity[]; }> async function GetViewportInfo(): Promise<{ p1: Vector3; p2: Vector3; ens: Entity[]; UCS: Matrix4; }>
{ {
const downStore = DownPanelStore.GetInstance(); const downStore = DownPanelStore.GetInstance();
let bak = downStore.isLayout; let bak = downStore.isLayout;
@ -65,7 +65,7 @@ async function GetViewportInfo(): Promise<{ p1: Vector3; p2: Vector3; ens: Entit
let p2 = rectRes.Point2UCS; let p2 = rectRes.Point2UCS;
let retEntitys = ens.length === 0 ? app.Database.ModelSpace.Entitys.filter(e => !e.IsErase) : ens; let retEntitys = ens.length === 0 ? app.Database.ModelSpace.Entitys.filter(e => !e.IsErase) : ens;
return { return {
p1, p2, ens: retEntitys p1, p2, ens: retEntitys, UCS: rectRes.UCS
}; };
} }
else if (rectRes.Status === PromptStatus.Keyword) else if (rectRes.Status === PromptStatus.Keyword)
@ -103,7 +103,7 @@ export class DrawViewport implements Command
if (data) if (data)
{ {
const { p1, p2, ens } = data; const { p1, p2, ens, UCS } = data;
let vp = new ViewportEntity(); let vp = new ViewportEntity();
vp.UpdateByPts(p1, p2); vp.UpdateByPts(p1, p2);
@ -116,6 +116,7 @@ export class DrawViewport implements Command
vp.AppendShowObjects(ids); vp.AppendShowObjects(ids);
vp.camera.LookAt(GetViewDirection(store.m_Option.view)); vp.camera.LookAt(GetViewDirection(store.m_Option.view));
vp.RenderType = store.m_Option.renderType; vp.RenderType = store.m_Option.renderType;
vp.ApplyMatrix(UCS);
app.Database.LayoutSpace.Append(vp); app.Database.LayoutSpace.Append(vp);
vp.ZoomAll(); vp.ZoomAll();
} }
@ -134,7 +135,7 @@ export class Draw4Viewport implements Command
if (data) if (data)
{ {
const { p1, p2, ens } = data; const { p1, p2, ens, UCS } = data;
AppToaster.show({ AppToaster.show({
message: "正在生成布局,请稍后", message: "正在生成布局,请稍后",
timeout: 0, timeout: 0,
@ -146,6 +147,7 @@ export class Draw4Viewport implements Command
for (let v of vps) for (let v of vps)
{ {
await Sleep(0); await Sleep(0);
v.ApplyMatrix(UCS);
app.Database.LayoutSpace.Append(v); app.Database.LayoutSpace.Append(v);
v.ZoomAll(); v.ZoomAll();
} }
@ -341,7 +343,7 @@ export class Draw2Viewport implements Command
const data = await GetViewportInfo(); const data = await GetViewportInfo();
if (!data) return; if (!data) return;
const { p1, p2, ens } = data; const { p1, p2, ens, UCS } = data;
let width = Math.abs(p1.x - p2.x); let width = Math.abs(p1.x - p2.x);
let height = Math.abs(p1.y - p2.y); let height = Math.abs(p1.y - p2.y);
@ -376,6 +378,8 @@ export class Draw2Viewport implements Command
vp2.camera.LookAt(GetViewDirection(store.m_Option.view2)); vp2.camera.LookAt(GetViewDirection(store.m_Option.view2));
vp1.RenderType = store.m_Option.renderType[0]; vp1.RenderType = store.m_Option.renderType[0];
vp2.RenderType = store.m_Option.renderType[1]; vp2.RenderType = store.m_Option.renderType[1];
vp1.ApplyMatrix(UCS);
vp2.ApplyMatrix(UCS);
app.Database.LayoutSpace.Append(vp1); app.Database.LayoutSpace.Append(vp1);
app.Database.LayoutSpace.Append(vp2); app.Database.LayoutSpace.Append(vp2);
vp1.ZoomAll(); vp1.ZoomAll();
@ -397,7 +401,7 @@ export class Draw3Viewport implements Command
if (!data) return; if (!data) return;
const { p1, p2, ens } = data; const { p1, p2, ens, UCS } = data;
let basePt = new Vector3(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y)); let basePt = new Vector3(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y));
@ -476,6 +480,7 @@ export class Draw3Viewport implements Command
vp.AppendShowObjects(ids); vp.AppendShowObjects(ids);
vp.camera.LookAt(GetViewDirection(store.m_Option.view[i])); vp.camera.LookAt(GetViewDirection(store.m_Option.view[i]));
vp.RenderType = store.m_Option.renderType[i]; vp.RenderType = store.m_Option.renderType[i];
vp.ApplyMatrix(UCS);
app.Database.LayoutSpace.Append(vp); app.Database.LayoutSpace.Append(vp);
vp.ZoomAll(); vp.ZoomAll();
await Sleep(0); await Sleep(0);

@ -356,7 +356,7 @@ function ConverSweep2Data(e: SweepSolid)
ed.Type = "Sweep"; ed.Type = "Sweep";
ed.OCS = e.OCSNoClone.toArray(); ed.OCS = e.OCSNoClone.toArray();
ed.Contour = Curve2Data(e.Contour); ed.Contour = Curve2Data(e.Contour);
ed.Path = Curve2Data(e.Path); ed.Path = Array.isArray(e.Path) ? e.Path.map((v) => Curve2Data(v)) : Curve2Data(e.Path);
ed.MaterialId = e.Material?.Object?.Id?.Index || 71; ed.MaterialId = e.Material?.Object?.Id?.Index || 71;
let roomName = e instanceof HardwareTopline ? e.HardwareOption.roomName : "未命名"; let roomName = e instanceof HardwareTopline ? e.HardwareOption.roomName : "未命名";
ed.RoomName = roomName; ed.RoomName = roomName;

@ -20,7 +20,7 @@ import { ObjectId } from "../../DatabaseServices/ObjectId";
import { PhysicalMaterialRecord } from '../../DatabaseServices/PhysicalMaterialRecord'; import { PhysicalMaterialRecord } from '../../DatabaseServices/PhysicalMaterialRecord';
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
import { equalv3, GetEulerAngle } from "../../Geometry/GeUtils"; import { GetEulerAngle, equalv3 } from "../../Geometry/GeUtils";
import { AppConfirm } from '../../UI/Components/Common/Confirm'; import { AppConfirm } from '../../UI/Components/Common/Confirm';
import { AppToaster } from "../../UI/Components/Toaster"; import { AppToaster } from "../../UI/Components/Toaster";
import { BoardType, LinesType } from "../../UI/Store/BoardInterface"; import { BoardType, LinesType } from "../../UI/Store/BoardInterface";
@ -516,14 +516,32 @@ export class KjlExport implements Command
let path = sw.Path; let path = sw.Path;
let size = sw.BoundingBoxInOCS.getSize(new Vector3); let size = sw.BoundingBoxInOCS.getSize(new Vector3);
let = { //轮廓信息
let contourData = {
points: this.GetPtNumberList(contour), points: this.GetPtNumberList(contour),
curves: this.GetCurveList(contour), curves: this.GetCurveList(contour),
}; };
let = { let pathPoints: number[] = [];
points: this.GetPtNumberList(path), let pathCurves: IKJLCurve[] = [];
curves: this.GetCurveList(path), if (Array.isArray(path))
{
for (let subPath of path)
{
pathPoints.push(...this.GetPtNumberList(subPath));
pathCurves.push(...this.GetCurveList(subPath));
}
}
else
{
pathPoints = this.GetPtNumberList(path);
pathCurves = this.GetCurveList(path);
}
//路径信息
let pathData = {
points: pathPoints,
curves: pathCurves,
}; };
const model: IReferenceSubModel = { const model: IReferenceSubModel = {
@ -557,7 +575,7 @@ export class KjlExport implements Command
}, },
{ {
name: "SLLJ", name: "SLLJ",
value: JSON.stringify() value: JSON.stringify(pathData)
}, },
{ {
name: "CZ", name: "CZ",
@ -565,7 +583,7 @@ export class KjlExport implements Command
}, },
{ {
name: "SLLK", name: "SLLK",
value: JSON.stringify() value: JSON.stringify(contourData)
} }
], ],
}; };

@ -1,4 +1,4 @@
import { Box3, Vector3 } from "three"; import { Box3, Matrix4, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { Draw } from "../../Common/Draw"; import { Draw } from "../../Common/Draw";
import { Log, LogType } from "../../Common/Log"; import { Log, LogType } from "../../Common/Log";
@ -37,7 +37,7 @@ export class Command_DrawRectWall implements Command
wall.AutoUpdate = false; wall.AutoUpdate = false;
}; };
const UpdateDraw = (p1: Vector3, p3: Vector3, updateDraw = true) => const UpdateDraw = (p1: Vector3, p3: Vector3, ucs: Matrix4, updateDraw = true) =>
{ {
if (this._DrawDirMode !== WallDirMode.Center) if (this._DrawDirMode !== WallDirMode.Center)
{ {
@ -86,7 +86,6 @@ export class Command_DrawRectWall implements Command
}; };
let p2 = new Vector3, p4 = new Vector3; let p2 = new Vector3, p4 = new Vector3;
let ucs = app.Editor.UCSMatrix;
while (true) while (true)
{ {
@ -94,9 +93,9 @@ export class Command_DrawRectWall implements Command
let rectRes = await app.Editor.GetRectPoint({ let rectRes = await app.Editor.GetRectPoint({
SupportSnapPoints: RoomWallParse._CacheWallNodePoints, SupportSnapPoints: RoomWallParse._CacheWallNodePoints,
Callback: (p1, p3) => Callback: (p1, p3, ucs) =>
{ {
UpdateDraw(p1, p3); UpdateDraw(p1, p3, ucs);
}, },
KeyWordList: [ KeyWordList: [
...WallModelKeyWords.filter((k, i) => i !== this._DrawDirMode), ...WallModelKeyWords.filter((k, i) => i !== this._DrawDirMode),
@ -105,7 +104,7 @@ export class Command_DrawRectWall implements Command
if (rectRes.Status === PromptStatus.OK) if (rectRes.Status === PromptStatus.OK)
{ {
UpdateDraw(rectRes.Point1UCS, rectRes.Point2UCS, false); UpdateDraw(rectRes.Point1UCS, rectRes.Point2UCS, rectRes.UCS, false);
let rrd = new RoomWallRemoveDuplicate(walls, GetAllWalls());//删除重复 let rrd = new RoomWallRemoveDuplicate(walls, GetAllWalls());//删除重复

@ -6,11 +6,11 @@ import { EBoardKeyList } from "../../Common/BoardKeyList";
import { IRectInfo, IsRect } from "../../Common/CurveUtils"; import { IRectInfo, IsRect } from "../../Common/CurveUtils";
import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox"; import { GroupEntitysByBox } from "../../Common/GroupEntitysByBox";
import { ToplineUrls } from "../../Common/HostUrl"; import { ToplineUrls } from "../../Common/HostUrl";
import { inflateBase64 } from "../../Common/inflate";
import { KeyWord } from "../../Common/InputState"; import { KeyWord } from "../../Common/InputState";
import { PostJson, RequestStatus } from "../../Common/Request"; import { PostJson, RequestStatus } from "../../Common/Request";
import { GroupFileIn } from "../../Common/SerializeMaterial"; import { GroupFileIn } from "../../Common/SerializeMaterial";
import { Sleep } from "../../Common/Sleep"; import { Sleep } from "../../Common/Sleep";
import { inflateBase64 } from "../../Common/inflate";
import { Hole } from "../../DatabaseServices/3DSolid/Hole"; import { Hole } from "../../DatabaseServices/3DSolid/Hole";
import { SweepSolid } from "../../DatabaseServices/3DSolid/SweepSolid"; import { SweepSolid } from "../../DatabaseServices/3DSolid/SweepSolid";
import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension"; import { AlignedDimension } from "../../DatabaseServices/Dimension/AlignedDimension";
@ -420,8 +420,8 @@ export class OneKeyLayout implements Command
if (rRes.Status === PromptStatus.OK) if (rRes.Status === PromptStatus.OK)
{ {
p1 = rRes.Point1UCS; p1 = rRes.Point1UCS.applyMatrix4(rRes.UCS);
p2 = rRes.Point2UCS; p2 = rRes.Point2UCS.applyMatrix4(rRes.UCS);
} }
else if (rRes.Status === PromptStatus.Cancel) else if (rRes.Status === PromptStatus.Cancel)
{ {

@ -1,4 +1,5 @@
import { app } from "../../ApplicationServices/Application"; import { app } from "../../ApplicationServices/Application";
import { Log } from "../../Common/Log";
import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline"; import { HardwareTopline } from "../../DatabaseServices/Hardware/HardwareTopline";
import { Command } from "../../Editor/CommandMachine"; import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult"; import { PromptStatus } from "../../Editor/PromptResult";
@ -10,15 +11,29 @@ export class Command_TestSweepMaxLength implements Command
{ {
async exec() async exec()
{ {
let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [HardwareTopline] }, Msg: "选" }); let enRes = await app.Editor.GetEntity({ Filter: { filterTypes: [HardwareTopline] }, Msg: "选择一个顶线,测试它的拆单尺寸" });
if (enRes.Status !== PromptStatus.OK) return; if (enRes.Status !== PromptStatus.OK) return;
let br = enRes.Entity as HardwareTopline; let topLine = enRes.Entity as HardwareTopline;
let b = br.Path.Clone();
b.Erase(false); Log("放样路径:红色, 轮廓:黄色, 拆单尺寸:绿色");
TestDraw(b, 1);
//@ts-ignore //1 绘制 path(放样路径)
TestDraw(br.Contours.map(c => c.ApplyMatrix(br.OCS)), 2); if (Array.isArray(topLine.Path))
TestDraw(br.Segmentations.map(c => c.ApplyMatrix(br.OCS)), 3); for (let p of topLine.Path)
br.Erase(); {
let path = p.Clone().ApplyMatrix(topLine.OCSNoClone);
path.Erase(false);
TestDraw(path, 1);
}
else
{
let path = topLine.Path.Clone().ApplyMatrix(topLine.OCSNoClone);
path.Erase(false);
TestDraw(path, 1);
}
//2.绘制最大线段
for (let seg of topLine.Segmentations)
TestDraw(seg.ApplyMatrix(topLine.OCSNoClone), 3);
} }
} }

@ -1,14 +1,16 @@
import { Box3, BoxBufferGeometry, BufferGeometry, Float32BufferAttribute, InstancedInterleavedBuffer, InterleavedBufferAttribute, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Line as TLine, Vector3 } from "three"; import { Box3, BoxBufferGeometry, BufferGeometry, Float32BufferAttribute, InstancedInterleavedBuffer, InterleavedBufferAttribute, LineSegments, Matrix3, Matrix4, Mesh, Object3D, Shape, Line as TLine, Vector2, Vector3 } from "three";
import { Line2 } from "three/examples/jsm/lines/Line2"; import { Line2 } from "three/examples/jsm/lines/Line2";
import { LineGeometry } from "three/examples/jsm/lines/LineGeometry"; import { LineGeometry } from "three/examples/jsm/lines/LineGeometry";
import { arrayRemoveDuplicateBySort } from "../../Common/ArrayExt"; import { arrayRemoveDuplicateBySort } from "../../Common/ArrayExt";
import { ColorMaterial } from '../../Common/ColorPalette'; import { ColorMaterial } from '../../Common/ColorPalette';
import { curveLinkGroup } from "../../Common/CurveUtils";
import { DisposeThreeObj, Object3DRemoveAll } from '../../Common/Dispose'; import { DisposeThreeObj, Object3DRemoveAll } from '../../Common/Dispose';
import { Log, LogType } from "../../Common/Log"; import { Log, LogType } from "../../Common/Log";
import { tempMatrix1 } from "../../Common/Matrix4Utils"; import { tempMatrix1 } from "../../Common/Matrix4Utils";
import { UpdateDraw } from "../../Common/Status"; import { UpdateDraw } from "../../Common/Status";
import { FixIndex } from "../../Common/Utils";
import { ObjectSnapMode } from "../../Editor/ObjectSnapMode"; import { ObjectSnapMode } from "../../Editor/ObjectSnapMode";
import { AsVector3, MoveMatrix, equaln, equalv3, isParallelTo } from '../../Geometry/GeUtils'; import { AsVector3, MoveMatrix, ZAxis, ZeroVec, equaln, equalv2, equalv3, isParallelTo } from '../../Geometry/GeUtils';
import { ProjectionToPlane, SweepGeometry } from '../../Geometry/SweepGeometry'; import { ProjectionToPlane, SweepGeometry } from '../../Geometry/SweepGeometry';
import { RenderType } from "../../GraphicsSystem/RenderType"; import { RenderType } from "../../GraphicsSystem/RenderType";
import { Factory } from "../CADFactory"; import { Factory } from "../CADFactory";
@ -25,9 +27,9 @@ export class SweepSolid extends Entity
{ {
static UseRectFakerContour = false; static UseRectFakerContour = false;
private _Contour: Polyline; protected _Contour: Polyline;
private _PathCurve: Curve; protected _PathCurve: Curve | Curve[];
constructor(contour?: Polyline, pathCurve?: Curve) constructor(contour?: Polyline, pathCurve?: Curve | Curve[])
{ {
super(); super();
this._Contour = contour; this._Contour = contour;
@ -39,15 +41,32 @@ export class SweepSolid extends Entity
if (this._Contour && this._PathCurve) if (this._Contour && this._PathCurve)
{ {
this.TransfromPathToWCS(); this.TransfromPathToWCS();
this.OCS = this._PathCurve.OCS;
this._SpaceOCS.copy(this._PathCurve.OCS); //将OCS变换成第一个路径的OCS(合理一点)
this._PathCurve.ApplyMatrix(this._PathCurve.OCSInv); let paths = this.Paths;
let path = paths[0];
this.OCS = path.OCSNoClone;
this._SpaceOCS.copy(path.OCSNoClone);
let ocsInv = this.OCSInv;
for (let p of paths)
p.ApplyMatrix(ocsInv);
} }
} }
Explode() Explode()
{ {
return [this._Contour.Clone(), this._PathCurve.Clone()]; if (Array.isArray(this._PathCurve))
{
const explode: Curve[] = [this._Contour.Clone().ApplyMatrix(this._Matrix)];
for (let path of this._PathCurve)
{
explode.push(path.Clone().ApplyMatrix(this._Matrix));
}
return explode;
}
return [this._Contour.Clone().ApplyMatrix(this._Matrix), this._PathCurve.Clone().ApplyMatrix(this._Matrix)];
} }
get Contour() get Contour()
@ -58,10 +77,23 @@ export class SweepSolid extends Entity
{ {
return this._PathCurve; return this._PathCurve;
} }
//单纯的返回数组
get Paths()
{
return Array.isArray(this._PathCurve) ? this._PathCurve : [this._PathCurve];
}
Reverse() Reverse()
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
this._PathCurve.Reverse(); if (Array.isArray(this._PathCurve))
{
for (let path of this._PathCurve)
path.Reverse();
this._PathCurve.reverse();
}
else this._PathCurve.Reverse();
this.Update(); this.Update();
} }
@ -70,7 +102,8 @@ export class SweepSolid extends Entity
*/ */
private TransfromPathToWCS() private TransfromPathToWCS()
{ {
if (equalv3(this._Contour.Normal, new Vector3(0, 0, 1))) if (Array.isArray(this._PathCurve)) return;
if (equalv3(this._Contour.Normal, ZAxis))
return; return;
let fDir = this._PathCurve.GetFistDeriv(0); let fDir = this._PathCurve.GetFistDeriv(0);
@ -128,6 +161,7 @@ export class SweepSolid extends Entity
} }
Log("错误:提供的轮廓没有和路径垂直!", LogType.Error); Log("错误:提供的轮廓没有和路径垂直!", LogType.Error);
} }
private _MeshGeometry: SweepGeometry; private _MeshGeometry: SweepGeometry;
private _lineGeo: LineGeometry; private _lineGeo: LineGeometry;
get MeshGeometry() get MeshGeometry()
@ -175,7 +209,21 @@ export class SweepSolid extends Entity
InitDrawObject(renderType: RenderType): Object3D InitDrawObject(renderType: RenderType): Object3D
{ {
if (renderType === RenderType.Wireframe || renderType === RenderType.Edge) if (renderType === RenderType.Wireframe || renderType === RenderType.Edge)
return new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(this.ColorIndex)); {
let line = new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(this.ColorIndex));
// for (let p of this.Paths)
// {
// p.IsEmbedEntity = true;
// let lineObj = p.GetDrawObjectFromRenderType(RenderType.Wireframe) as TLine;
// lineObj.material = ColorMaterial.GetWallLineMtl(1);
// lineObj.computeLineDistances();
// lineObj.matrix.copy(p.OCSNoClone);
// line.add(lineObj);
// }
return line;
}
else if (renderType === RenderType.Conceptual) else if (renderType === RenderType.Conceptual)
{ {
return new Object3D().add( return new Object3D().add(
@ -195,6 +243,13 @@ export class SweepSolid extends Entity
} }
else if (renderType === RenderType.Jig) else if (renderType === RenderType.Jig)
{ {
if (Array.isArray(this._PathCurve))
{
const object3d = new Object3D();
for (let path of this._PathCurve)
object3d.add(path.DrawObject);
return object3d;
}
return new Object3D().add(this._PathCurve.DrawObject); return new Object3D().add(this._PathCurve.DrawObject);
} }
else if (renderType === RenderType.Physical2) else if (renderType === RenderType.Physical2)
@ -220,6 +275,16 @@ export class SweepSolid extends Entity
let l = obj as LineSegments; let l = obj as LineSegments;
l.geometry = this.EdgeGeometry; l.geometry = this.EdgeGeometry;
l.material = ColorMaterial.GetLineMaterial(this.ColorIndex); l.material = ColorMaterial.GetLineMaterial(this.ColorIndex);
// Object3DRemoveAll(l);
// for (let p of this.Paths)
// {
// p.IsEmbedEntity = true;
// let lineObj = p.GetDrawObjectFromRenderType(RenderType.Wireframe) as TLine;
// lineObj.material = ColorMaterial.GetWallLineMtl(1);
// lineObj.computeLineDistances();
// l.add(lineObj);
// }
} }
else if (renderType === RenderType.Conceptual) else if (renderType === RenderType.Conceptual)
{ {
@ -238,7 +303,11 @@ export class SweepSolid extends Entity
else if (renderType === RenderType.Jig) else if (renderType === RenderType.Jig)
{ {
Object3DRemoveAll(obj); Object3DRemoveAll(obj);
obj.add((this._PathCurve.DrawObject)); if (Array.isArray(this._PathCurve))
for (let path of this._PathCurve)
obj.add(path.DrawObject);
else
obj.add((this._PathCurve.DrawObject));
} }
else if (renderType === RenderType.Physical2) else if (renderType === RenderType.Physical2)
{ {
@ -311,12 +380,29 @@ export class SweepSolid extends Entity
case ObjectSnapMode.Per: case ObjectSnapMode.Per:
case ObjectSnapMode.Tan: case ObjectSnapMode.Tan:
{ {
let contour = this._PathCurve.Clone(); if (Array.isArray(this._PathCurve))
contour.ApplyMatrix(this.OCS); {
let pts = contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform); const points: Vector3[] = [];
if (snapMode === ObjectSnapMode.Mid) for (let path of this._PathCurve)
return [...pts, ...this.GetMidPoints()]; {
return pts; let contour = path.Clone();
contour.ApplyMatrix(this.OCS);
let pts = contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform);
if (snapMode === ObjectSnapMode.Mid)
points.push(...pts, ...this.GetMidPoints());
else points.push(...pts);
}
return points;
}
else
{
let contour = this._PathCurve.Clone();
contour.ApplyMatrix(this.OCS);
let pts = contour.GetObjectSnapPoints(snapMode, pickPoint, lastPoint, viewXform);
if (snapMode === ObjectSnapMode.Mid)
return [...pts, ...this.GetMidPoints()];
return pts;
}
} }
default: default:
break; break;
@ -324,68 +410,154 @@ export class SweepSolid extends Entity
return []; return [];
} }
GetGripPoints() //缓存夹点和子实体的索引
private _GripSubIndexMap: Map<number, Entity>;
/** 获取夹点与子实体的索引 */
GetGripSubIndexMap()
{ {
let pts = this._PathCurve.GetGripPoints(); if (this._GripSubIndexMap)
for (let p of pts) return this._GripSubIndexMap;
p.applyMatrix4(this._Matrix);
return pts; this.GetGripPoints();
return this._GripSubIndexMap;
} }
GetStretchPoints()
GetGripPoints()
{ {
let pts = this._PathCurve.GetStretchPoints(); this._GripSubIndexMap = undefined;
for (let p of pts)
p.applyMatrix4(this._Matrix); if (Array.isArray(this._PathCurve))
return pts; {
this._GripSubIndexMap = new Map;
const points: Vector3[] = [];
for (let path of this._PathCurve)
{
let pts = path.GetGripPoints();
for (let p of pts)
{
this._GripSubIndexMap.set(points.length, path);
p.applyMatrix4(this._Matrix);
points.push(p);
}
}
return points;
}
else
{
let pts = this._PathCurve.GetGripPoints();
for (let p of pts)
p.applyMatrix4(this._Matrix);
return pts;
}
} }
private UpdateEndMtx(dir: Vector3, pos: Vector3)
GetStretchPoints()
{ {
let y = this.Normal; if (Array.isArray(this._PathCurve))
let roMat = new Matrix4().extractRotation(this.OCS); {
let z = dir.applyMatrix4(roMat); const points: Vector3[] = [];
let x = z.clone().cross(y); for (let path of this._PathCurve)
tempMatrix1.makeBasis(x, y, z); {
tempMatrix1.setPosition(pos.applyMatrix4(this.OCS)); let pts = path.GetStretchPoints();
for (let p of pts)
{
p.applyMatrix4(this._Matrix);
points.push(p);
}
}
return points;
}
else
{
let pts = this._PathCurve.GetStretchPoints();
for (let p of pts)
p.applyMatrix4(this._Matrix);
return pts;
}
} }
//端点捕捉时提供端点 //端点捕捉时提供端点
private GetEndPoint() private GetEndPoint()
{ {
let pathPts: Vector3[] = [];
let pathNormals: Vector3[] = [];
//路径点表 //路径点表
let pathPts2d = this._PathCurve.Shape.getPoints(4); if (Array.isArray(this._PathCurve))
let pathPts = pathPts2d.map(AsVector3); {
arrayRemoveDuplicateBySort(pathPts, equalv3); for (let path of this._PathCurve)
{
let pathPts2d = path.Shape.getPoints(4) as Vector2[];
arrayRemoveDuplicateBySort(pathPts2d, (p1, p2) =>
{
if (equalv2(p1, p2))
{
p2["_mask_"] = p1["_mask_"];
return true;
}
return false;
});
if (path !== this._PathCurve[0])
pathPts2d.shift();
for (let p of pathPts) let pNormal = path.Normal;
p.applyMatrix4(this._PathCurve.OCS);
for (let p of pathPts2d)
{
let p3 = AsVector3(p).applyMatrix4(path.OCSNoClone);
p3["_mask_"] = p["_mask_"];
pathPts.push(p3);
pathNormals.push(pNormal);
}
}
}
else
{
const path = this._PathCurve;
//路径点表
let pathPts2d = (path.Shape as Shape).getPoints(4);
pathPts = pathPts2d.map(AsVector3);
arrayRemoveDuplicateBySort(pathPts, equalv3);
let pNormal = path.Normal;
for (let p of pathPts)
{
p.applyMatrix4(path.OCSNoClone);
pathNormals.push(pNormal);
}
}
let shapePts2d = this.Contour.Shape.getPoints(4); let shapePts2d = this.Contour.Shape.getPoints(4);
// if (!ShapeUtils.isClockWise(shapePts2d)) shapePts2d.reverse();
//轮廓点表 //轮廓点表
let shapePts3d = shapePts2d.map(AsVector3); let shapePts3d = shapePts2d.map(AsVector3);
let isClosePath = equalv3(pathPts[0], pathPts[pathPts.length - 1], 1e-3);
for (let p of shapePts3d) for (let p of shapePts3d)
p.applyMatrix4(this.Contour.OCSNoClone); p.applyMatrix4(this.Contour.OCSNoClone);
let pts: Vector3[] = [];//端点 let pts: Vector3[] = [];//端点
//遍历路径节点 // arrayPushArray(pts, pathPts);
//遍历所有的路径节点进行顶点投射
for (let i = 1; i < pathPts.length; i++) for (let i = 1; i < pathPts.length; i++)
{ {
if (i === pathPts.length - 1) if (i === pathPts.length - 1)
{ {
if (this._PathCurve.IsClose) if (isClosePath)
pts.push(...ProjectionToPlane(shapePts3d, this._PathCurve.Normal, pathPts[i], pathPts[i - 1], pathPts[1])); pts.push(...ProjectionToPlane(shapePts3d, pathNormals[i], pathPts[i], pathPts[i - 1], pathPts[1]));
else else
pts.push(...ProjectionToPlane(shapePts3d, this._PathCurve.Normal, pathPts[i], pathPts[i - 1])); pts.push(...ProjectionToPlane(shapePts3d, pathNormals[i], pathPts[i], pathPts[i - 1]));
} }
else else
pts.push(...ProjectionToPlane(shapePts3d, this._PathCurve.Normal, pathPts[i], pathPts[i - 1], pathPts[i + 1])); {
pts.push(...ProjectionToPlane(shapePts3d, pathNormals[i], pathPts[i], pathPts[i - 1], pathPts[i + 1]));
}
} }
for (let p of pts) p.applyMatrix4(this.OCSNoClone); for (let pt of pts) pt.applyMatrix4(this.OCSNoClone);
return pts; return pts;
} }
@ -393,49 +565,204 @@ export class SweepSolid extends Entity
{ {
let conPts = this._Contour.GetStretchPoints(); let conPts = this._Contour.GetStretchPoints();
const pts: Vector3[] = []; const pts: Vector3[] = [];
const UpdateEndMtx = (path: Curve) =>
for (let i = 0.5; i < this._PathCurve.EndParam; i++)
{ {
let p = this._PathCurve.GetPointAtParam(i); for (let i = 0.5; i < path.EndParam; i++)
let d1 = this._PathCurve.GetFistDeriv(i).normalize(); {
this.UpdateEndMtx(d1, p); let pos = path.GetPointAtParam(i);
pts.push(...conPts.map(p => p.clone().applyMatrix4(tempMatrix1))); let dir = path.GetFistDeriv(i).normalize();
} let y = path.Normal;
let roMat = new Matrix4().extractRotation(this.OCS);
let z = dir.applyMatrix4(roMat);
let x = z.clone().cross(y);
tempMatrix1.makeBasis(x, y, z);
tempMatrix1.setPosition(pos.applyMatrix4(this.OCS));
pts.push(...conPts.map(p => p.clone().applyMatrix4(tempMatrix1)));
}
};
if (Array.isArray(this._PathCurve))
for (let path of this._PathCurve)
UpdateEndMtx(path);
else
UpdateEndMtx(this._PathCurve);
return pts; return pts;
} }
MoveGripPoints(indexList: number[], vec: Vector3) MoveGripPoints(indexList: number[], vec: Vector3)
{ {
if (equalv3(vec, ZeroVec)) return;
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
this.IfPathIsLineThenZ0Vector(vec); vec = vec.clone().applyMatrix4(this.OCSInv.setPosition(0, 0, 0));
this._PathCurve.MoveGripPoints(indexList, if (Array.isArray(this._PathCurve))
vec.clone().applyMatrix4(new Matrix4().extractRotation(this.OCSInv))); {
this.Update(); let ptsLengths = 0;
} for (let i = 0; i < this._PathCurve.length; i += 1)
{
const path = this._PathCurve[i];
const pathGripPts = path.GetGripPoints();
const idxList = indexList.filter(v => v >= ptsLengths && v < (ptsLengths + pathGripPts.length)).map((v) => v - ptsLengths);
//如果路径是直线,我们在这里避免vec传递z轴信息 ptsLengths += pathGripPts.length;
private IfPathIsLineThenZ0Vector(vec: Vector3)
{ if (idxList.length === 0) continue;
if (this._PathCurve instanceof Line)
let isMoveLine = (path instanceof Line && idxList.length === 1 && idxList[0] === 1);
let isMovePolylineStart = (path instanceof Polyline) && idxList.length === 1 && idxList.includes(1);
let isMovePolylineEnd = (path instanceof Polyline) && idxList.length === 1 && idxList.includes(pathGripPts.length - 2);
//如果不是整体移动,那么vec被限制在CURVE OCS Z0
let isMove = isMoveLine || idxList.length === pathGripPts.length;
if (!isMove)
{
vec = vec.clone()
.applyMatrix4(path.OCSInv.setPosition(0, 0, 0))
.setZ(0)
.applyMatrix4(path.OCS.setPosition(0, 0, 0));
}
//我们校验它的前后曲线支不支持它移动这个点
let prePath = this._PathCurve[FixIndex(i - 1, this._PathCurve)];
let nextPath = this._PathCurve[FixIndex(i + 1, this._PathCurve)];
if ((isMoveLine || idxList.includes(0) || isMovePolylineStart)//(move line ) or (move start) or(move pl start)
&& (i || equalv3(prePath.EndPoint, path.StartPoint, 1e-3)))//连接到下一段
{
//vec限制在上一段的坐标系内 无z
vec = vec.clone()
.applyMatrix4(prePath.OCSInv.setPosition(0, 0, 0))
.setZ(0)
.applyMatrix4(prePath.OCS.setPosition(0, 0, 0));
if (isMoveLine || isMovePolylineStart)//顺带移动上一段
prePath.MoveGripPoints([prePath.GetGripPoints().length - 1], vec);
}
if ((isMoveLine || idxList.includes(pathGripPts.length - 1) || isMovePolylineEnd)//(move line ) or (move end) or(move pl end)
&& (i < this._PathCurve.length - 2 || equalv3(path.EndPoint, nextPath.StartPoint, 1e-3)))//连接到上一段
{
//vec限制在下一段的坐标系内 无z
vec = vec.clone()
.applyMatrix4(nextPath.OCSInv.setPosition(0, 0, 0))
.setZ(0)
.applyMatrix4(nextPath.OCS.setPosition(0, 0, 0));
if (isMoveLine || isMovePolylineEnd)//顺带移动下一段
nextPath.MoveGripPoints([0], vec);
}
if (isMove)
path.Move(vec);
else
path.MoveGripPoints(idxList, vec);
}
}
else
{ {
let ocsinv = this._PathCurve.OCSInv.setPosition(0, 0, 0); this._PathCurve.MoveGripPoints(indexList, vec);
vec.applyMatrix4(ocsinv).setZ(0);
vec.applyMatrix4(this._PathCurve.OCSNoClone);
} }
this.Update();
} }
MoveStretchPoints(indexList: number[], vec: Vector3) MoveStretchPoints(indexList: number[], vec: Vector3)
{ {
if (equalv3(vec, ZeroVec)) return;
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
this.IfPathIsLineThenZ0Vector(vec); vec = vec.clone().applyMatrix4(this.OCSInv.setPosition(0, 0, 0));
if (Array.isArray(this._PathCurve))
{
let ptsLengths = 0;
let pathIndexMap = new Map<Curve, {
idx: number[];
count: number,
isMove: boolean,
}>();
//1.parse
for (let i = 0; i < this._PathCurve.length; i++)
{
let path = this._PathCurve[i];
const pts = path.GetStretchPoints();
const idxList = indexList.filter(v => v >= ptsLengths && v < (ptsLengths + pts.length)).map((v) => v - ptsLengths);
ptsLengths += pts.length;
pathIndexMap.set(path, {
idx: idxList,
count: pts.length,
isMove: pts.length === idxList.length,
});
}
//2.change vec
for (let i = 0; i < this._PathCurve.length; i++)
{
let path = this._PathCurve[i];
let { idx: idxList, count: ptsCount, isMove } = pathIndexMap.get(path);
if (idxList.length === 0) continue;
let isMoveStart = idxList.includes(0);
let isMoveEnd = idxList.includes(ptsCount - 1);
if (!isMove)//如果不是移动 限制在本OCS内 NO Z
{
vec.applyMatrix4(path.OCSInv.setPosition(0, 0, 0))
.setZ(0)
.applyMatrix4(path.OCS.setPosition(0, 0, 0));
}
//我们校验它的前后曲线支不支持它移动这个点
let prePath = this._PathCurve[FixIndex(i - 1, this._PathCurve)];
let nextPath = this._PathCurve[FixIndex(i + 1, this._PathCurve)];
//如果pre是move 则不需要过滤z
if ((isMove || isMoveStart)//(move line ) or (move start) or(move pl start)
&& (i || equalv3(prePath.EndPoint, path.StartPoint, 1e-3))//连接到下一段
&& (!pathIndexMap.get(prePath).isMove)//非移动
)
{
//vec限制在上一段的坐标系内 无z
vec.applyMatrix4(prePath.OCSInv.setPosition(0, 0, 0))
.setZ(0)
.applyMatrix4(prePath.OCS.setPosition(0, 0, 0));
}
if (
isMove || isMoveEnd
&& (i < this._PathCurve.length - 2 || equalv3(path.EndPoint, nextPath.StartPoint, 1e-3))//连接到上一段
&& (!pathIndexMap.get(nextPath).isMove)//非移动
)
{
//vec限制在下一段的坐标系内 无z
vec.applyMatrix4(nextPath.OCSInv.setPosition(0, 0, 0))
.setZ(0)
.applyMatrix4(nextPath.OCS.setPosition(0, 0, 0));
}
}
this._PathCurve.MoveStretchPoints(indexList, //3 move
vec.clone().applyMatrix4(new Matrix4().extractRotation(this.OCSInv))); for (let i = 0; i < this._PathCurve.length; i++)
{
let path = this._PathCurve[i];
let { idx: idxList, isMove } = pathIndexMap.get(path);
if (isMove)
path.Move(vec);
else
path.MoveStretchPoints(idxList, vec);
}
}
else
{
this._PathCurve.MoveStretchPoints(indexList, vec);
}
this.Update(); this.Update();
} }
ApplyMatrix(m: Matrix4) ApplyMatrix(m: Matrix4)
{ {
this.WriteAllObjectRecord(); this.WriteAllObjectRecord();
@ -467,37 +794,67 @@ export class SweepSolid extends Entity
this._Matrix.multiplyMatrices(m, this._Matrix); this._Matrix.multiplyMatrices(m, this._Matrix);
return this; return this;
} }
let ocsInv = this.OCSInv; let ocsInv = this.OCSInv;
this._PathCurve.ApplyMatrix(this.OCS).ApplyMatrix(m).ApplyMatrix(ocsInv); if (Array.isArray(this._PathCurve))
{
for (let p of this._PathCurve)
p.ApplyMatrix(this.OCSNoClone).ApplyMatrix(m).ApplyMatrix(ocsInv);
let mtx = this._PathCurve.OCS; let group = curveLinkGroup(this._PathCurve);
let mtxInv = new Matrix4().getInverse(mtx); this._PathCurve = group[0];
this._PathCurve.ApplyMatrix(mtxInv); }
this._SpaceOCS.copy(this._Matrix); else
this._Matrix.multiplyMatrices(this._Matrix, mtx); this._PathCurve.ApplyMatrix(this.OCSNoClone).ApplyMatrix(m).ApplyMatrix(ocsInv);
this.Update(UpdateDraw.Geometry); this.Update(UpdateDraw.Geometry);
return this; return this;
} }
protected _ReadFile(file: CADFiler) protected _ReadFile(file: CADFiler)
{ {
super._ReadFile(file); super._ReadFile(file);
let ver = file.Read();//1 let ver = file.Read();//ver
this._Contour = file.ReadObject() as Polyline; this._Contour = file.ReadObject() as Polyline;
this._PathCurve = file.ReadObject() as Curve; if (ver === 1)
if (this._Contour instanceof Spline || this._PathCurve instanceof Spline)
{ {
this._isErase = true; this._PathCurve = file.ReadObject() as Curve;
Log("放样实体是样条线生成的,自动删除它!", LogType.Info); if (this._Contour instanceof Spline || this._PathCurve instanceof Spline)
{
this._isErase = true;
Log("放样实体是样条线生成的,自动删除它!", LogType.Info);
}
}
else if (ver > 1)
{
const pathCurveCount = file.Read();
if (pathCurveCount === 1)
this._PathCurve = file.ReadObject() as Curve;
else
{
this._PathCurve = [];
for (let i = 0; i < pathCurveCount; i++)
{
this._PathCurve.push(file.ReadObject());
}
}
} }
} }
WriteFile(file: CADFiler) WriteFile(file: CADFiler)
{ {
super.WriteFile(file); super.WriteFile(file);
file.Write(1);//ver file.Write(2);//ver
file.WriteObject(this._Contour); file.WriteObject(this._Contour);
file.WriteObject(this._PathCurve); if (Array.isArray(this._PathCurve))
{
file.Write(this._PathCurve.length);
for (let c of this._PathCurve)
file.WriteObject(c);
}
else
{
file.Write(1);
file.WriteObject(this._PathCurve);
}
} }
} }

@ -1,4 +1,4 @@
import { Box3, BufferGeometry, Line as TLine, Line3, Matrix3, Matrix4, Object3D, Shape, Vector3 } from 'three'; import { Box3, BufferGeometry, Line3, Matrix3, Matrix4, Object3D, Shape, Line as TLine, Vector3 } from 'three';
import { Line2 } from 'three/examples/jsm/lines/Line2'; import { Line2 } from 'three/examples/jsm/lines/Line2';
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'; import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry';
import { ColorMaterial } from '../../Common/ColorPalette'; import { ColorMaterial } from '../../Common/ColorPalette';
@ -7,7 +7,7 @@ import { Status } from '../../Common/Status';
import { ObjectSnapMode } from '../../Editor/ObjectSnapMode'; import { ObjectSnapMode } from '../../Editor/ObjectSnapMode';
import { Box3Ext } from '../../Geometry/Box'; import { Box3Ext } from '../../Geometry/Box';
import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils'; import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils';
import { AsVector2, equaln, equalv3, isParallelTo, MoveMatrix, updateGeometry } from '../../Geometry/GeUtils'; import { AsVector2, MoveMatrix, equaln, equalv3, isParallelTo, updateGeometry } from '../../Geometry/GeUtils';
import { PlaneExt } from '../../Geometry/Plane'; import { PlaneExt } from '../../Geometry/Plane';
import { ROTATE_MTX2 } from '../../Geometry/RotateUV'; import { ROTATE_MTX2 } from '../../Geometry/RotateUV';
import { IntersectEllipseAndLine, IntersectLineAndArc, IntersectLineAndCircle, IntersectLineAndLine, IntersectOption, IntersectPolylineAndCurve, IntersectResult, reverseIntersectOption } from '../../GraphicsSystem/IntersectWith'; import { IntersectEllipseAndLine, IntersectLineAndArc, IntersectLineAndCircle, IntersectLineAndLine, IntersectOption, IntersectPolylineAndCurve, IntersectResult, reverseIntersectOption } from '../../GraphicsSystem/IntersectWith';
@ -402,7 +402,7 @@ export class Line extends Curve
return this; return this;
} }
GetOffsetCurves(offsetDist: number): Array<Curve> GetOffsetCurves(offsetDist: number): Array<Line>
{ {
let offset = this._EndPoint.clone().sub(this._StartPoint).normalize().multiplyScalar(offsetDist); let offset = this._EndPoint.clone().sub(this._StartPoint).normalize().multiplyScalar(offsetDist);
ROTATE_MTX2.applyVector(offset); ROTATE_MTX2.applyVector(offset);

@ -1207,9 +1207,9 @@ export class Polyline extends Curve
/** /**
* *
*/ */
Explode(): Curve[] Explode(): (Line | Arc)[]
{ {
let exportCus: Curve[] = []; let exportCus: (Line | Arc)[] = [];
for (let i = 0; i < this.EndParam; i++) for (let i = 0; i < this.EndParam; i++)
{ {
exportCus.push(this.GetCurveAtIndex(i)); exportCus.push(this.GetCurveAtIndex(i));
@ -1257,7 +1257,7 @@ export class Polyline extends Curve
* 线,. * 线,.
* @param {number} i * @param {number} i
*/ */
GetCurveAtIndex(i: number): Curve GetCurveAtIndex(i: number): Line | Arc
{ {
if (i >= this._LineData.length) return undefined; if (i >= this._LineData.length) return undefined;
@ -1268,7 +1268,7 @@ export class Polyline extends Curve
let d1 = this._LineData[i]; let d1 = this._LineData[i];
let d2 = this._LineData[FixIndex(i + 1, this._LineData)]; let d2 = this._LineData[FixIndex(i + 1, this._LineData)];
let curve: Curve; let curve: Line | Arc;
if (equaln(d1.bul, 0, BUL_IS_LINE_FUZZ)) if (equaln(d1.bul, 0, BUL_IS_LINE_FUZZ))
curve = new Line(AsVector3(d1.pt), AsVector3(d2.pt)).ApplyMatrix(this.OCSNoClone); curve = new Line(AsVector3(d1.pt), AsVector3(d2.pt)).ApplyMatrix(this.OCSNoClone);
else else

@ -1,15 +1,15 @@
import { Matrix4 } from "three"; import { Matrix4, Vector3 } from "three";
import { arrayRemoveIf } from "../../Common/ArrayExt"; import { FixIndex } from "../../Common/Utils";
import { GetPointAtCurveDir } from "../../Common/CurveUtils";
import { DefaultToplineMetalsOption } from "../../Editor/DefaultConfig"; import { DefaultToplineMetalsOption } from "../../Editor/DefaultConfig";
import { equaln, isPerpendicularityTo, rotatePoint, ZAxis } from "../../Geometry/GeUtils"; import { AsVector3, ZeroVec, equalv3 } from "../../Geometry/GeUtils";
import { IntersectOption } from "../../GraphicsSystem/IntersectWith"; import { ProjectionToPlane } from "../../Geometry/SweepGeometry";
import { FixIndex } from "../../Nest/Common/Util"; import { Max } from "../../Nest/Common/Util";
import { IToplineOption } from "../../UI/Components/RightPanel/RightPanelInterface"; import { IToplineOption } from "../../UI/Components/RightPanel/RightPanelInterface";
import { SweepSolid } from '../3DSolid/SweepSolid'; import { SweepSolid } from "../3DSolid/SweepSolid";
import { AutoRecord, AutoRecordObject } from "../AutoRecord"; import { AutoRecord, AutoRecordObject } from "../AutoRecord";
import { Factory } from "../CADFactory"; import { Factory } from "../CADFactory";
import { CADFiler } from "../CADFiler"; import { CADFiler } from "../CADFiler";
import { Arc } from "../Entity/Arc";
import { Curve } from "../Entity/Curve"; import { Curve } from "../Entity/Curve";
import { Line } from "../Entity/Line"; import { Line } from "../Entity/Line";
import { Polyline } from "../Entity/Polyline"; import { Polyline } from "../Entity/Polyline";
@ -24,193 +24,112 @@ export class HardwareTopline extends SweepSolid
{ {
return this._contourRotation; return this._contourRotation;
} }
private _ContourWidth: number;
private get Contours(): Curve[]
{
let c = this.Path;
let conBox = this.Contour.BoundingBox;
let cMin = conBox.min;
let cMax = conBox.max;
let y = ZAxis;
let z = c.GetFistDeriv(0).normalize();
let x = z.clone().cross(y);
let mat = new Matrix4().makeBasis(x, y, z);
mat.setPosition(c.StartPoint);
[cMin, cMax].forEach(p => p.applyMatrix4(mat).setZ(0));
let firstCurve: Curve;
if (c instanceof Polyline)
firstCurve = c.GetCurveAtParam(0);
else
firstCurve = c;
let closePt = firstCurve.GetClosestPointTo(cMin, false);
let offset = cMin.distanceTo(closePt);
let dir = GetPointAtCurveDir(firstCurve, cMin);
let cus = this.Path.GetOffsetCurves(offset * dir);
let l1 = cus[0] ?? this.Path.Clone();
closePt = firstCurve.GetClosestPointTo(cMax, false);
let offset2 = cMax.distanceTo(closePt);
dir = GetPointAtCurveDir(firstCurve, cMax);
cus = this.Path.GetOffsetCurves(offset2 * dir);
let l2 = cus[0] ?? this.Path.Clone();
this._ContourWidth = offset + offset2;
return [l1, l2];
}
/** /**
*线,线 *线,线
*
*/ */
get Segmentations(): Curve[] get Segmentations(): Curve[]
{ {
const [l1, l2] = this.Contours; //轮廓点表
if (!(l1 instanceof Polyline)) let contourPts = this._Contour.Shape.getPoints(4).map(AsVector3);
return [l1]; for (let p of contourPts)
p.applyMatrix4(this._Contour.OCSNoClone);
let cus1 = l1.Explode() as Curve[];
let cus2 = l2.Explode() as Curve[]; //收集所有的点
let pathCurves: (Line | Arc)[] = [];
[cus1, cus2] = cus1.length < cus2.length ? [cus2, cus1] : [cus1, cus2]; if (Array.isArray(this._PathCurve))
let sgs: Curve[] = [];
const AddSgs = (c1: Curve, c2: Curve) =>
{ {
sgs.push(c1.Length > c2.Length ? c1 : c2); for (let p of this._PathCurve)
};
const ExtendCurve = (c: Curve, refC: Curve, isPre) =>
{
let pts = c.IntersectWith2(refC, IntersectOption.ExtendBoth).filter(r =>
{ {
if (isPre) if (p instanceof Polyline)
return r.thisParam < 0; pathCurves.push(...p.Explode() as Line[]);
else else
return r.thisParam > 1; pathCurves.push(p.Clone() as Line);
});
if (isPre)
{
pts.sort((r1, r2) => r2.thisParam - r1.thisParam);
if (pts.length > 0 && pts[0].thisParam < 0)
c.Extend(pts[0].thisParam);
} }
}
else
if (this._PathCurve instanceof Polyline)
pathCurves.push(...this._PathCurve.Explode() as Line[]);
else else
{ pathCurves.push(this._PathCurve.Clone() as Line);
pts.sort((r1, r2) => r1.thisParam - r2.thisParam);
if (pts.length > 0 && pts[0].thisParam > 1)
c.Extend(pts[0].thisParam);
}
};
const IsNoRelativeCurve = (c1: Curve, c2: Curve) =>
{
if ((c1 instanceof Line) !== (c2 instanceof Line))
return true;
let midPt = c1.GetPointAtParam(0.5);
let closePt = c2.GetClosestPointTo(midPt, false);
return !closePt || !equaln(midPt.distanceTo(closePt), this._ContourWidth, 1e-3);
};
const HasRelativeCurveAndChange = (target: Curve, cs: Curve[], isChange = false) => let isClosePath = equalv3(pathCurves[0].StartPoint, pathCurves[pathCurves.length - 1].EndPoint, 1e-3);
{
let index = cs.findIndex(c => !IsNoRelativeCurve(c, target));
if (index !== -1)
{
if (isChange && l1.IsClose)
cs.unshift(...cs.splice(index));
return true;
}
return false;
};
if (cus1.length !== cus2.length) let radiusMap = new Map<Arc, number>();
arrayRemoveIf(cus2, c => !HasRelativeCurveAndChange(c, cus1));
for (let i = 0; i < cus1.length; i++) function ExtendsCurve(path: Curve, pts: Vector3[])
{ {
let c1 = cus1[i]; let params = pts.map(p => path.GetParamAtPoint2(path.GetClosestPointTo(p, true)));
let c2 = cus2[i];
if (cus1.length !== cus2.length) let min = Math.min(0, params[Max(params, (p1, p2) => p1 > p2)]);
{ let max = Math.max(1, params[Max(params, (p1, p2) => p1 < p2)]);
if (IsNoRelativeCurve(c1, c2))
{
sgs.push(c1);
cus1.splice(i, 1);
i--;
continue;
}
}
else
{
//第一段验证是否是关联段,不关联重置数组顺序
if (i === 0)
{
if (IsNoRelativeCurve(c1, c2))
{
if (!HasRelativeCurveAndChange(c1, cus2, true))
{
console.error("错误");
return cus1;
}
i--;
continue;
}
}
}
let nextC1: Curve; let sp = path.GetPointAtParam(min);
let ep = path.GetPointAtParam(max);
if (l1.IsClose) path.StartPoint = sp;
{ path.EndPoint = ep;
nextC1 = cus1[FixIndex(i + 1, cus1.length)]; }
}
else //遍历所有的路径节点进行顶点投射
for (let i = 0; i < pathCurves.length; i++)
{
let path = pathCurves[i];
if (isClosePath || i !== pathCurves.length - 1)//与下一段
{ {
if (i < cus1.length - 1) let ep = path.EndPoint;
let nextPath = pathCurves[FixIndex(i + 1, pathCurves)];
let preP: Vector3;
if (path instanceof Line)
preP = ep.clone().sub(path.GetFistDeriv(1).normalize());
else
{ {
nextC1 = cus1[i + 1]; let pts = path.Shape.getPoints(4);
preP = AsVector3(pts[pts.length - 2]).applyMatrix4(path.OCSNoClone);
} }
} let nextP: Vector3;
if (nextPath instanceof Line)
if (nextC1) nextP = ep.clone().add(nextPath.GetFistDeriv(0).normalize());
{ else
let derv = c1.GetFistDeriv(0).normalize();
let derv2 = nextC1.GetFistDeriv(0).normalize();
if (isPerpendicularityTo(derv, derv2) && isPerpendicularityTo(derv, c1.StartPoint.sub(c2.StartPoint).normalize()))
{ {
AddSgs(c1, c2); let pts = nextPath.Shape.getPoints(4);
continue; nextP = AsVector3(pts[1]).applyMatrix4(nextPath.OCSNoClone);
} }
}
let nextDerv1 = c1.GetFistDeriv(1).normalize(); //投射的点表
let nextDerv2 = c2.GetFistDeriv(1).normalize(); let pts = ProjectionToPlane(contourPts, path.Normal, ep, preP, nextP);
let preDerv1 = c1.GetFistDeriv(0).normalize();
let preDerv2 = c2.GetFistDeriv(0).normalize();
[nextDerv1, nextDerv2, preDerv1, preDerv2].forEach(d => rotatePoint(d, Math.PI / 2));
let preRefLine1 = new Line(c1.StartPoint, c1.StartPoint.add(preDerv1)); // for (let j = 0; j < pts.length - 1; j++)
let preRefLine2 = new Line(c2.StartPoint, c2.StartPoint.add(preDerv2)); // TestDraw(new Line(pts[j].clone(), pts[j + 1].clone()).ApplyMatrix(this.OCSNoClone), i + 1);
let nextRefLine1 = new Line(c1.EndPoint, c1.EndPoint.add(nextDerv1)); //针对圆弧 修改它的半径
let nextRefLine2 = new Line(c2.EndPoint, c2.EndPoint.add(nextDerv2)); if (path instanceof Arc)
{
ExtendCurve(c1, nextRefLine2, false); let mp = path.GetPointAtParam(0.5);
ExtendCurve(c2, nextRefLine1, false); let arcPts = ProjectionToPlane(contourPts, path.Normal, mp, mp.clone().sub(path.GetFistDeriv(0.5).normalize()));
let r = radiusMap.get(path);
let ocsInv = path.OCSInv;
let radius = arcPts.map(p => p.applyMatrix4(ocsInv).setZ(0).distanceTo(ZeroVec));
if (r) radius.push(r);
let maxRadius = radius[Max(radius, (r1, r2) => r1 < r2)];
radiusMap.set(path, maxRadius);
}
ExtendCurve(c1, preRefLine2, true);
ExtendCurve(c2, preRefLine1, true);
AddSgs(c1, c2); ExtendsCurve(path, pts);
ExtendsCurve(nextPath, pts);
}
} }
return sgs; for (let [arc, rad] of radiusMap)
arc.Radius = rad;
return pathCurves;
} }
get MaxLength() get MaxLength()
{ {
return this.Segmentations.reduce((len, c) => len + c.Length, 0); return this.Segmentations.reduce((len, c) => len + c.Length, 0);
@ -226,11 +145,11 @@ export class HardwareTopline extends SweepSolid
this.Contour.ApplyMatrix(mat); this.Contour.ApplyMatrix(mat);
this.Update(); this.Update();
} }
protected _ReadFile(file: CADFiler) protected _ReadFile(file: CADFiler)
{ {
super._ReadFile(file); super._ReadFile(file);
let ver = file.Read();//1 let ver = file.Read();//1
this._contourRotation = file.Read(); this._contourRotation = file.Read();
this.HardwareOption.addLen = file.Read(); this.HardwareOption.addLen = file.Read();
@ -254,7 +173,6 @@ export class HardwareTopline extends SweepSolid
d[1] = file.Read(); d[1] = file.Read();
this.DataList.push(d); this.DataList.push(d);
} }
} }
WriteFile(file: CADFiler) WriteFile(file: CADFiler)
{ {

@ -10,6 +10,7 @@ import { ConfigTagCommand } from '../UI/Components/Board/ConfigTagCommand';
import { AppToaster } from '../UI/Components/Toaster'; import { AppToaster } from '../UI/Components/Toaster';
import { CommandState } from './CommandState'; import { CommandState } from './CommandState';
import { JigUtils } from './JigUtils'; import { JigUtils } from './JigUtils';
import { UCSUtils } from './UCSRAII';
import { userConfig } from './UserConfig'; import { userConfig } from './UserConfig';
export interface Command export interface Command
{ {
@ -139,6 +140,7 @@ class CommandMachine
{ {
//先把Jig实体清除了,避免残影 //先把Jig实体清除了,避免残影
JigUtils.End(); JigUtils.End();
UCSUtils.End();
let hasHistory = !noHistory && app.Database.hm.CurrentHasHistory(); let hasHistory = !noHistory && app.Database.hm.CurrentHasHistory();
//先执行反应器 //先执行反应器

@ -12,6 +12,7 @@ import { GetRectPointPromptBlock } from "../UI/DynamicPrompt/GetRectPointPromptB
import { IsKeyword } from "./InitKeyword"; import { IsKeyword } from "./InitKeyword";
import { PromptRectPointOptions } from "./PromptOptions"; import { PromptRectPointOptions } from "./PromptOptions";
import { PromptRectResult, PromptStatus } from "./PromptResult"; import { PromptRectResult, PromptStatus } from "./PromptResult";
import { GetPointUCS } from "./UCSRAII";
export class GetRectPointServices export class GetRectPointServices
{ {
@ -26,7 +27,8 @@ export class GetRectPointServices
private dynPrompt: GetRectPointPromptBlock; private dynPrompt: GetRectPointPromptBlock;
private destroyCalls = []; private destroyCalls = [];
private _UCSMatrix: Matrix4; private _UCSMatrixBak: Matrix4;//备份UCS矩阵
private _CurUCSMtx: Matrix4;
async Start(prompt: PromptRectPointOptions = {}): Promise<PromptRectResult> async Start(prompt: PromptRectPointOptions = {}): Promise<PromptRectResult>
{ {
@ -36,15 +38,23 @@ export class GetRectPointServices
this.promisResolve = resolve; this.promisResolve = resolve;
let basePoint = prompt.BasePoint; let basePoint = prompt.BasePoint;
this._UCSMatrixBak = app.Editor.UCSMatrix;
if (!basePoint) if (!basePoint)
{ {
let ptRes = await app.Editor.GetPoint({ let ptRes = await app.Editor.GetPoint({
Msg: prompt.Msg || "请输入或者点取第一个角点:", Msg: prompt.Msg || "请输入或者点取第一个角点:",
KeyWordList: prompt.KeyWordList, KeyWordList: prompt.KeyWordList,
SupportSnapPoints: prompt.SupportSnapPoints, SupportSnapPoints: prompt.SupportSnapPoints,
Raycast: true,
}); });
if (ptRes.Status === PromptStatus.OK) if (ptRes.Status === PromptStatus.OK)
{
basePoint = ptRes.Point; basePoint = ptRes.Point;
//设置合理的UCS
app.Editor.UCSMatrix = GetPointUCS(ptRes) ?? this._UCSMatrixBak.clone().setPosition(basePoint);
}
else if (ptRes.Status === PromptStatus.Keyword) else if (ptRes.Status === PromptStatus.Keyword)
{ {
let res = new PromptRectResult(); let res = new PromptRectResult();
@ -59,14 +69,15 @@ export class GetRectPointServices
return; return;
} }
} }
else//设置合理的UCS
app.Editor.UCSMatrix = this._UCSMatrixBak.clone().setPosition(basePoint);
this._CurUCSMtx = app.Editor.UCSMatrix;
this.dynPrompt = new GetRectPointPromptBlock(); this.dynPrompt = new GetRectPointPromptBlock();
let ucsInv = app.Editor.UCSMatrixInv; let ucsInv = app.Editor.UCSMatrixInv;
let basePointUCS = basePoint.clone().applyMatrix4(ucsInv); let basePointUCS = basePoint.clone().applyMatrix4(ucsInv);
//备份坐标系,结束时还原它,(当捕获的点不在当前的UCS平面时)
this._UCSMatrix = app.Editor.UCSMatrix;
app.Editor.UCSMatrix = this._UCSMatrix.clone().setPosition(basePoint);
let signX = 1; let signX = 1;
let signY = 1; let signY = 1;
@ -147,7 +158,7 @@ export class GetRectPointServices
this.UpdateDynPrompt(basePointUCS, p2UCS); this.UpdateDynPrompt(basePointUCS, p2UCS);
if (prompt.Callback) if (prompt.Callback)
prompt.Callback(basePointUCS, p2UCS); prompt.Callback(basePointUCS, p2UCS, this._CurUCSMtx);
} }
}); });
if (ptRes.Status === PromptStatus.OK) if (ptRes.Status === PromptStatus.OK)
@ -155,6 +166,8 @@ export class GetRectPointServices
let res = new PromptRectResult(); let res = new PromptRectResult();
res.Status = PromptStatus.OK; res.Status = PromptStatus.OK;
res.UCS = this._CurUCSMtx;
res.Point1UCS = basePointUCS; res.Point1UCS = basePointUCS;
res.Point2UCS = ptRes.Point.applyMatrix4(ucsInv); res.Point2UCS = ptRes.Point.applyMatrix4(ucsInv);
@ -167,7 +180,7 @@ export class GetRectPointServices
res.Point2UCS.y = basePointUCS.y + this.dynPrompt.Height * signY; res.Point2UCS.y = basePointUCS.y + this.dynPrompt.Height * signY;
if (this.dynPrompt.xDynIpt.IsLock || this.dynPrompt.yDynIpt.IsLock) if (this.dynPrompt.xDynIpt.IsLock || this.dynPrompt.yDynIpt.IsLock)
res.Point2WCS.copy(res.Point2UCS).applyMatrix4(this._UCSMatrix); res.Point2WCS.copy(res.Point2UCS).applyMatrix4(this._CurUCSMtx);
this.ReturnResult(res); this.ReturnResult(res);
} }
@ -201,7 +214,7 @@ export class GetRectPointServices
]; ];
for (let p of pts) for (let p of pts)
{ {
p.applyMatrix4(this._UCSMatrix); p.applyMatrix4(this._CurUCSMtx);
app.Viewer.PreViewer.WorldToViewPoint(p); app.Viewer.PreViewer.WorldToViewPoint(p);
} }
BufferGeometryUtils.UpdatePts(this.rubberBandLine.geometry as BufferGeometry, pts, true); BufferGeometryUtils.UpdatePts(this.rubberBandLine.geometry as BufferGeometry, pts, true);
@ -246,12 +259,14 @@ export class GetRectPointServices
this.dynPrompt = undefined; this.dynPrompt = undefined;
} }
if (this._UCSMatrix) if (this._UCSMatrixBak)
{ {
app.Editor.UCSMatrix = this._UCSMatrix; app.Editor.UCSMatrix = this._UCSMatrixBak;
this._UCSMatrix = undefined; this._UCSMatrixBak = undefined;
} }
this._CurUCSMtx = undefined;//clear
this.destroyCalls.forEach(f => f()); this.destroyCalls.forEach(f => f());
} }
Cancel() Cancel()

@ -1,4 +1,4 @@
import { BufferGeometry, Line as TLine, Points, Vector3 } from 'three'; import { BufferGeometry, Points, Line as TLine, Vector3 } from 'three';
import { end } from 'xaop'; import { end } from 'xaop';
import { app } from '../ApplicationServices/Application'; import { app } from '../ApplicationServices/Application';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
@ -6,6 +6,7 @@ import { CommandNames } from '../Common/CommandNames';
import { InputState } from '../Common/InputState'; import { InputState } from '../Common/InputState';
import { MouseKey } from '../Common/KeyEnum'; import { MouseKey } from '../Common/KeyEnum';
import { GetEntity } from '../Common/Utils'; import { GetEntity } from '../Common/Utils';
import { SweepSolid } from '../DatabaseServices/3DSolid/SweepSolid';
import { Entity } from '../DatabaseServices/Entity/Entity'; import { Entity } from '../DatabaseServices/Entity/Entity';
import { Line } from '../DatabaseServices/Entity/Line'; import { Line } from '../DatabaseServices/Entity/Line';
import { RectAreaLight } from '../DatabaseServices/Lights/RectAreaLight'; import { RectAreaLight } from '../DatabaseServices/Lights/RectAreaLight';
@ -14,7 +15,7 @@ import { RoomWallBase } from '../DatabaseServices/Room/Entity/Wall/RoomWallBase'
import { WallSnapMode } from '../DatabaseServices/Room/Entity/Wall/WallSnapMode'; import { WallSnapMode } from '../DatabaseServices/Room/Entity/Wall/WallSnapMode';
import { RoomWallParse } from '../DatabaseServices/Room/ParseService/RoomWallParse'; import { RoomWallParse } from '../DatabaseServices/Room/ParseService/RoomWallParse';
import { BufferGeometryUtils } from '../Geometry/BufferGeometryUtils'; import { BufferGeometryUtils } from '../Geometry/BufferGeometryUtils';
import { isParallelTo, isPerpendicularityTo, SnapPoint } from '../Geometry/GeUtils'; import { SnapPoint, isParallelTo, isPerpendicularityTo } from '../Geometry/GeUtils';
import { PointShapeUtils } from '../Geometry/PointShapeUtils'; import { PointShapeUtils } from '../Geometry/PointShapeUtils';
import { DrawMode } from '../GraphicsSystem/PreViewer'; import { DrawMode } from '../GraphicsSystem/PreViewer';
import { CommandWrap } from './CommandMachine'; import { CommandWrap } from './CommandMachine';
@ -176,9 +177,19 @@ export class GripDragServices implements EditorService
//修改UCS //修改UCS
let oldUcs = app.Editor.UCSMatrix; let oldUcs = app.Editor.UCSMatrix;
if (snapIndexMap[0] && !(snapIndexMap[0].ent instanceof Line)) let ent = snapIndexMap[0]?.ent;
if (ent && ent instanceof SweepSolid && Array.isArray(ent.Path))
{ {
let ocs = snapIndexMap[0].ent.OCS; let map = ent.GetGripSubIndexMap();
ent = map.get(snapIndexMap[0].indexArr[0]);//我们以第一个点作为我们的拉伸坐标系
}
if (ent && !(ent instanceof Line))
{
let ocs = ent.OCS;
if (snapIndexMap[0].ent !== ent)
ocs.multiplyMatrices(snapIndexMap[0].ent.OCSNoClone, ocs);
let viewDir = app.Viewer.CameraCtrl.Direction; let viewDir = app.Viewer.CameraCtrl.Direction;
let z = new Vector3(); let z = new Vector3();
//如果对象坐标系和视图坐标系垂直,则修正坐标系 //如果对象坐标系和视图坐标系垂直,则修正坐标系
@ -191,9 +202,9 @@ export class GripDragServices implements EditorService
ocs.makeBasis(xv, yv, viewDir).setPosition(p); ocs.makeBasis(xv, yv, viewDir).setPosition(p);
} }
if (snapIndexMap[0].ent instanceof SpotLight && snapIndexMap[0].indexArr[0] > 2) if (ent instanceof SpotLight && snapIndexMap[0].indexArr[0] > 2)
ocs.setPosition(snapIndexMap[0].snapP); ocs.setPosition(snapIndexMap[0].snapP);
else if (snapIndexMap[0].ent instanceof RoomWallBase) else if (ent instanceof RoomWallBase)
{ {
SupportSnapPoints = RoomWallParse._CacheWallNodePoints; SupportSnapPoints = RoomWallParse._CacheWallNodePoints;
RoomWallBase.SnapMode = WallSnapMode.Center; RoomWallBase.SnapMode = WallSnapMode.Center;

@ -1,4 +1,4 @@
import { Intersection, Vector3 } from 'three'; import { Intersection, Matrix4, Vector3 } from 'three';
import { KeyWord } from '../Common/InputState'; import { KeyWord } from '../Common/InputState';
import { PromptEntityResult, PromptSsgetResult } from './PromptResult'; import { PromptEntityResult, PromptSsgetResult } from './PromptResult';
import { SelectType } from './SelectBox'; import { SelectType } from './SelectBox';
@ -64,7 +64,7 @@ export interface GetDistendPrompt extends PromptOptions
export interface PromptRectPointOptions extends PromptOptions export interface PromptRectPointOptions extends PromptOptions
{ {
BasePoint?: Vector3; BasePoint?: Vector3;
Callback?: (p1UCS: Vector3, p2UCS: Vector3) => void; Callback?: (p1UCS: Vector3, p2UCS: Vector3, UCS: Matrix4) => void;
// AllowDrawRubberBand?: Boolean; // AllowDrawRubberBand?: Boolean;
SupportSnapPoints?: Vector3[]; SupportSnapPoints?: Vector3[];
} }

@ -1,4 +1,4 @@
import { Intersection, Object3D, Vector3 } from 'three'; import { Intersection, Matrix4, Object3D, Vector3 } from 'three';
import { Entity } from '../DatabaseServices/Entity/Entity'; import { Entity } from '../DatabaseServices/Entity/Entity';
import { ObjectSnapMode } from './ObjectSnapMode'; import { ObjectSnapMode } from './ObjectSnapMode';
import { SelectSet } from './SelectSet'; import { SelectSet } from './SelectSet';
@ -79,6 +79,8 @@ export class PromptDistendResult extends PromptResult
export class PromptRectResult extends PromptResult export class PromptRectResult extends PromptResult
{ {
UCS: Matrix4;
Point1UCS: Vector3; Point1UCS: Vector3;
Point2UCS: Vector3; Point2UCS: Vector3;

@ -1,4 +1,4 @@
import { BufferGeometry, Line, Matrix3, Matrix4, Object3D, PerspectiveCamera, Vector3 } from 'three'; import { BufferGeometry, Line, Matrix3, Matrix4, Mesh, Object3D, PerspectiveCamera, Vector3 } from 'three';
import { app } from '../ApplicationServices/Application'; import { app } from '../ApplicationServices/Application';
import { ColorMaterial } from '../Common/ColorPalette'; import { ColorMaterial } from '../Common/ColorPalette';
import { GetEntity } from '../Common/Utils'; import { GetEntity } from '../Common/Utils';
@ -11,7 +11,7 @@ import { Polyline } from '../DatabaseServices/Entity/Polyline';
import { RoomWallBase } from '../DatabaseServices/Room/Entity/Wall/RoomWallBase'; import { RoomWallBase } from '../DatabaseServices/Room/Entity/Wall/RoomWallBase';
import { BufferGeometryUtils } from '../Geometry/BufferGeometryUtils'; import { BufferGeometryUtils } from '../Geometry/BufferGeometryUtils';
import { CurveIntersection } from '../Geometry/CurveIntersection'; import { CurveIntersection } from '../Geometry/CurveIntersection';
import { equaln, equalv3, midPoint, SnapPoint, XAxis, YAxis, ZAxis } from '../Geometry/GeUtils'; import { SnapPoint, XAxis, YAxis, ZAxis, equaln, equalv3, midPoint } from '../Geometry/GeUtils';
import { PointShapeUtils } from '../Geometry/PointShapeUtils'; import { PointShapeUtils } from '../Geometry/PointShapeUtils';
import { IntersectOption } from '../GraphicsSystem/IntersectWith'; import { IntersectOption } from '../GraphicsSystem/IntersectWith';
import { DrawMode } from '../GraphicsSystem/PreViewer'; import { DrawMode } from '../GraphicsSystem/PreViewer';
@ -19,6 +19,7 @@ import { Max } from '../Nest/Common/Util';
import { DynamicInputManage } from '../UI/DynamicPrompt/DynamicInputManage'; import { DynamicInputManage } from '../UI/DynamicPrompt/DynamicInputManage';
import { PromptBlock } from '../UI/DynamicPrompt/PromptBlock'; import { PromptBlock } from '../UI/DynamicPrompt/PromptBlock';
import { ObjectSnapMode } from './ObjectSnapMode'; import { ObjectSnapMode } from './ObjectSnapMode';
import { GenerateRaycaster, Raycast } from './PointPick';
import { GetPointPrompt } from "./PromptOptions"; import { GetPointPrompt } from "./PromptOptions";
import { SelectPick } from './SelectPick'; import { SelectPick } from './SelectPick';
@ -87,12 +88,14 @@ export class SnapServices
private _SupportSnapPoints: SupportSnapPoint[] = [];//辅助捕捉点WCS private _SupportSnapPoints: SupportSnapPoint[] = [];//辅助捕捉点WCS
private _LockSuppotPointIndex = -1;//只允许删除这个后面的辅助捕捉点 private _LockSuppotPointIndex = -1;//只允许删除这个后面的辅助捕捉点
private _UCS: Matrix4; private _UCS: Matrix4;
private _Prompt: GetPointPrompt;
/** 切线捕捉时使用的基点 */ /** 切线捕捉时使用的基点 */
TanBasePoint: Vector3; TanBasePoint: Vector3;
//开始捕捉 //开始捕捉
Start(prompt: GetPointPrompt) Start(prompt: GetPointPrompt)
{ {
this._Prompt = prompt;
this._UCS = app.Editor.UCSMatrix; this._UCS = app.Editor.UCSMatrix;
this.InitDynPrompt(); this.InitDynPrompt();
@ -305,6 +308,12 @@ export class SnapServices
let selectEns = sel.SelectEntityList; let selectEns = sel.SelectEntityList;
//收集Mesh(以便我们过滤点击穿透)
let selectMeshs: Mesh[] = [];
for (let obj of sel._SelectList)
if (obj instanceof Mesh)
selectMeshs.push(obj);
let viewXform = new Matrix3().setFromMatrix4(app.Viewer.Camera.matrix); let viewXform = new Matrix3().setFromMatrix4(app.Viewer.Camera.matrix);
//如果只有切线捕捉 //如果只有切线捕捉
@ -345,7 +354,7 @@ export class SnapServices
bp = this.TanBasePoint; bp = this.TanBasePoint;
let ens = mode === ObjectSnapMode.Cen ? circles : selectEns; let ens = mode === ObjectSnapMode.Cen ? circles : selectEns;
let snapData = this.CalcClosestSnapPoint(ens, mode, wcsP, vcsP, bp, viewXform); let snapData = this.CalcClosestSnapPoint(ens, selectMeshs, mode, wcsP, vcsP, bp, viewXform);
if (snapData.Point) if (snapData.Point)
{ {
@ -393,6 +402,20 @@ export class SnapServices
for (let p of pts) for (let p of pts)
{ {
let pv = app.Viewer.WorldToScreen(p.clone()); let pv = app.Viewer.WorldToScreen(p.clone());
//避免捕捉穿透
if (selectMeshs.length)
{
let ray = GenerateRaycaster(pv, app.Viewer);
let i = Raycast(ray, selectMeshs);
if (i)
{
let d = i.point.subVectors(p, i.point).dot(ray.ray.direction);
if (d > 0.1)
continue;
}
}
if (SnapPoint(vcsP, pv, this.SnapSize)) if (SnapPoint(vcsP, pv, this.SnapSize))
{ {
this.SnapType = ObjectSnapMode.Int; this.SnapType = ObjectSnapMode.Int;
@ -407,7 +430,7 @@ export class SnapServices
//#region 最近点捕捉 //#region 最近点捕捉
if (this.SnapModeEnable & ObjectSnapMode.Nea) if (this.SnapModeEnable & ObjectSnapMode.Nea)
{ {
let snapData = this.CalcClosestSnapPoint(selectEns, ObjectSnapMode.Nea, wcsP, vcsP, baseP, viewXform); let snapData = this.CalcClosestSnapPoint(selectEns, selectMeshs, ObjectSnapMode.Nea, wcsP, vcsP, baseP, viewXform);
if (snapData.Point) if (snapData.Point)
{ {
this.SnapType = ObjectSnapMode.Nea; this.SnapType = ObjectSnapMode.Nea;
@ -418,7 +441,9 @@ export class SnapServices
} }
//计算最近的捕捉点 //计算最近的捕捉点
private CalcClosestSnapPoint(selectEns: Entity[], private CalcClosestSnapPoint(
selectEns: Entity[],
selectMeshs: Mesh[],
mode: ObjectSnapMode, mode: ObjectSnapMode,
wcsP: Vector3, wcsP: Vector3,
vcsP: Vector3, vcsP: Vector3,
@ -445,6 +470,20 @@ export class SnapServices
let pv = app.Viewer.WorldToScreen(p.clone()); let pv = app.Viewer.WorldToScreen(p.clone());
let z = pv.z; let z = pv.z;
pv.z = 0; pv.z = 0;
//避免捕捉穿透
if (selectMeshs.length)
{
let ray = GenerateRaycaster(pv, app.Viewer);
let i = Raycast(ray, selectMeshs);
if (i)
{
let d = i.point.subVectors(p, i.point).dot(ray.ray.direction);
if (d > 0.1)
continue;
}
}
let dist = vcsP.distanceToSquared(pv); let dist = vcsP.distanceToSquared(pv);
if (equaln(dist, minDistance) && z < minZ) if (equaln(dist, minDistance) && z < minZ)
{ {

@ -0,0 +1,68 @@
import { Matrix4, Vector3 } from "three";
import { app } from "../ApplicationServices/Application";
import { Singleton } from "../Common/Singleton";
import { equalv3 } from "../Geometry/GeUtils";
import { Orbit } from "../Geometry/Orbit";
import { DownPanelStore } from "../UI/Store/DownPanelStore";
import { PromptPointResult } from "./PromptResult";
//通过拾取的点智能的给一个UCS
export function GetPointUCS(ptRes: PromptPointResult): Matrix4 | undefined
{
const downPanelStore = DownPanelStore.GetInstance();
if (downPanelStore.EnableSmartUCS && ptRes.intersection)
{
let ucs = app.Editor.UCSMatrix;
let ucsN = new Vector3().setFromMatrixColumn(ucs, 2);
let n = ptRes.intersection.face.normal.clone().transformDirection(ptRes.intersection.object.matrixWorld);
if (equalv3(n, ucsN))//如果相同
return ucs.setPosition(ptRes.Point);
let x = new Vector3;
let y = new Vector3;
Orbit.ComputUpDirection(n, y, x);
return new Matrix4().makeBasis(x, y, n).setPosition(ptRes.Point);
}
}
class UCSRAII extends Singleton
{
private _UCSBak: Matrix4;
private SaveUCS()
{
if (!this._UCSBak)
this._UCSBak = app.Editor.UCSMatrix;
}
set UCSMtx(mtx: Matrix4)
{
this.SaveUCS();
app.Editor.UCSMatrix = mtx;
}
SetUCSFromPointRes(ptRes: PromptPointResult): Matrix4 | undefined
{
let ucs = GetPointUCS(ptRes);
if (ucs)
{
this.SaveUCS();
app.Editor.UCSMatrix = ucs;
return ucs;
}
}
End()
{
if (this._UCSBak)
{
app.Editor.UCSMatrix = this._UCSBak;
this._UCSBak = undefined;
}
}
}
export const UCSUtils = UCSRAII.GetInstance();

@ -27,7 +27,7 @@ export class Point2SpaceParse extends ISpaceParse
if (rectRes.Status !== PromptStatus.OK) return; if (rectRes.Status !== PromptStatus.OK) return;
let depth = await GetSpaceDepth(rectRes.Point1UCS, rectRes.Point2UCS, app.Editor.UCSMatrix, lastDepth); let depth = await GetSpaceDepth(rectRes.Point1UCS, rectRes.Point2UCS, rectRes.UCS, lastDepth);
if (!depth) return; if (!depth) return;
lastDepth = depth; lastDepth = depth;

@ -1,9 +1,9 @@
import { Face3, Geometry, Line3, Matrix4, ShapeUtils, Vector2, Vector3 } from "three"; import { Face3, Geometry, Line3, Matrix4, Shape, ShapeUtils, Vector2, Vector3 } from "three";
import { arrayRemoveDuplicateBySort } from "../Common/ArrayExt"; import { arrayRemoveDuplicateBySort } from "../Common/ArrayExt";
import { Curve } from "../DatabaseServices/Entity/Curve"; import { Curve } from "../DatabaseServices/Entity/Curve";
import { Polyline } from "../DatabaseServices/Entity/Polyline"; import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { FixIndex } from "../Nest/Common/Util"; import { FixIndex } from "../Nest/Common/Util";
import { AsVector3, equalv3 } from "./GeUtils"; import { AsVector3, equalv2, equalv3 } from "./GeUtils";
import { PlaneExt } from "./Plane"; import { PlaneExt } from "./Plane";
/** /**
@ -13,11 +13,15 @@ import { PlaneExt } from "./Plane";
export class SweepGeometry extends Geometry export class SweepGeometry extends Geometry
{ {
edgePts: number[] = []; edgePts: number[] = [];
constructor(contour: Polyline, path: Curve) constructor(contour: Polyline, path: Curve[] | Curve)
{ {
super(); super();
this.AddShape(contour, path); if (Array.isArray(path))
this.AddShape2(contour, path);
else
this.AddShape(contour, path);
this.computeVertexNormals(); this.computeVertexNormals();
this.computeFaceNormals(); this.computeFaceNormals();
} }
@ -25,11 +29,11 @@ export class SweepGeometry extends Geometry
AddShape(contour: Polyline, path: Curve) AddShape(contour: Polyline, path: Curve)
{ {
//路径点表 //路径点表
let pathPts2d = path.Shape.getPoints(4); let pathPts2d = (path.Shape as Shape).getPoints(4);
let pathPts = pathPts2d.map(AsVector3); let pathPts = pathPts2d.map(AsVector3);
arrayRemoveDuplicateBySort(pathPts, equalv3); arrayRemoveDuplicateBySort(pathPts, equalv3);
for (let p of pathPts) for (let p of pathPts)
p.applyMatrix4(path.OCS); p.applyMatrix4(path.OCSNoClone);
let shapePts2d = contour.Shape.getPoints(4); let shapePts2d = contour.Shape.getPoints(4);
if (!ShapeUtils.isClockWise(shapePts2d)) shapePts2d.reverse(); if (!ShapeUtils.isClockWise(shapePts2d)) shapePts2d.reverse();
@ -38,36 +42,115 @@ export class SweepGeometry extends Geometry
let shapePts3d = shapePts2d.map(AsVector3); let shapePts3d = shapePts2d.map(AsVector3);
for (let p of shapePts3d) for (let p of shapePts3d)
p.applyMatrix4(contour.OCS); p.applyMatrix4(contour.OCSNoClone);
let isClosePath = path.IsClose; let isClosePath = path.IsClose;
let verts: Vector3[][] = [];//所有路径上的轮廓点 let verts: Vector3[][] = [];//所有路径上的轮廓点
let pathNormal = path.Normal;
//计算所有需要的几何点,本质是不断的投影 //计算所有需要的几何点,本质是不断的投影
if (isClosePath) if (!isClosePath)
verts.push(ProjectionToPlane(shapePts3d, path.Normal, pathPts[0], pathPts[pathPts.length - 2], pathPts[1])); verts.push(ProjectionToPlane(shapePts3d, pathNormal, pathPts[0], undefined, pathPts[1]));
else
verts.push(ProjectionToPlane(shapePts3d, path.Normal, pathPts[0], undefined, pathPts[1]));
//遍历所有的路径节点进行顶点投射 //遍历所有的路径节点进行顶点投射
for (let i = 1; i < pathPts.length; i++) for (let i = 1; i < pathPts.length; i++)
{ {
if (i === pathPts.length - 1) if (i === pathPts.length - 1)
{ {
if (isClosePath) if (isClosePath)
verts.push(ProjectionToPlane(shapePts3d, path.Normal, pathPts[i], pathPts[i - 1], pathPts[1])); verts.push(ProjectionToPlane(shapePts3d, pathNormal, pathPts[i], pathPts[i - 1], pathPts[1]));
else else
verts.push(ProjectionToPlane(shapePts3d, path.Normal, pathPts[i], pathPts[i - 1])); verts.push(ProjectionToPlane(shapePts3d, pathNormal, pathPts[i], pathPts[i - 1]));
} }
else else
{ {
verts.push(ProjectionToPlane(shapePts3d, path.Normal, pathPts[i], pathPts[i - 1], pathPts[i + 1])); verts.push(ProjectionToPlane(shapePts3d, pathNormal, pathPts[i], pathPts[i - 1], pathPts[i + 1]));
} }
} }
if (isClosePath)
verts.unshift(verts[verts.length - 1]);
this.BuildSideFaces(shapePts2d, pathPts2d, pathPts, verts); this.BuildSideFaces(shapePts2d, pathPts2d, pathPts, verts);
if (!isClosePath) this.BuildLid(shapePts2d, verts); if (!isClosePath) this.BuildLid(shapePts2d, verts);
} }
AddShape2(contour: Polyline, paths: Curve[])
{
let pathPts: Vector3[] = [];
let pathNormals: Vector3[] = [];
//路径点表
for (let path of paths)
{
let pathPts2d = path.Shape.getPoints(4) as Vector2[];
arrayRemoveDuplicateBySort(pathPts2d, (p1, p2) =>
{
if (equalv2(p1, p2))
{
p2["_mask_"] = p1["_mask_"];
return true;
}
return false;
});
if (path !== paths[0])
pathPts2d.shift();
let pNormal = path.Normal;
for (let p of pathPts2d)
{
let p3 = AsVector3(p).applyMatrix4(path.OCSNoClone);
p3["_mask_"] = p["_mask_"];
pathPts.push(p3);
pathNormals.push(pNormal);
}
}
let shapePts2d = contour.Shape.getPoints(4);
if (!ShapeUtils.isClockWise(shapePts2d)) shapePts2d.reverse();
//轮廓点表
let shapePts3d = shapePts2d.map(AsVector3);
for (let p of shapePts3d)
p.applyMatrix4(contour.OCSNoClone);
let isClosePath = equalv3(pathPts[0], pathPts[pathPts.length - 1], 1e-3);
let verts: Vector3[][] = [];//所有路径上的轮廓点
//计算所有需要的几何点,本质是不断的投影
if (!isClosePath)
verts.push(ProjectionToPlane(shapePts3d, pathNormals[0], pathPts[0], undefined, pathPts[1]));
//遍历所有的路径节点进行顶点投射
for (let i = 1; i < pathPts.length; i++)
{
if (i === pathPts.length - 1)
{
if (isClosePath)
verts.push(ProjectionToPlane(shapePts3d, pathNormals[i], pathPts[i], pathPts[i - 1], pathPts[1]));
else
verts.push(ProjectionToPlane(shapePts3d, pathNormals[i], pathPts[i], pathPts[i - 1]));
}
else
{
verts.push(ProjectionToPlane(shapePts3d, pathNormals[i], pathPts[i], pathPts[i - 1], pathPts[i + 1]));
}
}
if (isClosePath)
verts.unshift(verts[verts.length - 1]);
this.BuildSideFaces(shapePts2d, pathPts as unknown as Vector2[], pathPts, verts);
if (!isClosePath) this.BuildLid(shapePts2d, verts);
}
private BuildSideFaces(shapePts2d: Vector2[], pathPts2d: Vector2[], pathPts: Vector3[], verts: Vector3[][]) private BuildSideFaces(shapePts2d: Vector2[], pathPts2d: Vector2[], pathPts: Vector3[], verts: Vector3[][])
{ {
let addCount = 0; //补充个数 let addCount = 0; //补充个数

@ -15,7 +15,7 @@ import { Light } from '../../DatabaseServices/Lights/Light';
import { PointLight } from '../../DatabaseServices/Lights/PointLight'; import { PointLight } from '../../DatabaseServices/Lights/PointLight';
import { RectAreaLight } from '../../DatabaseServices/Lights/RectAreaLight'; import { RectAreaLight } from '../../DatabaseServices/Lights/RectAreaLight';
import { SpotLight } from '../../DatabaseServices/Lights/SpotLight'; import { SpotLight } from '../../DatabaseServices/Lights/SpotLight';
import { commandMachine, CommandWrap } from '../../Editor/CommandMachine'; import { CommandWrap, commandMachine } from '../../Editor/CommandMachine';
import { CommandState } from '../../Editor/CommandState'; import { CommandState } from '../../Editor/CommandState';
import { LightsMenu } from '../../Editor/LightsMenu'; import { LightsMenu } from '../../Editor/LightsMenu';
import { SnapMenuFixed } from '../../Editor/SnapMenuFixed'; import { SnapMenuFixed } from '../../Editor/SnapMenuFixed';
@ -575,6 +575,19 @@ export class DownPanel extends React.Component<{ store: DownPanelStore; }, {}>
/> />
</Tooltip> </Tooltip>
} }
<Tooltip
content="当拾取点在三维面上时,自动设置UCS为面上的坐标系"
position={Position.TOP}
>
<Switch
checked={this.downStore.EnableSmartUCS}
label="智能UCS"
style={switchStyle}
alignIndicator={Alignment.RIGHT}
data-key="smartUCS"
onChange={this.handleChange}
/>
</Tooltip>
</div> </div>
</div> </div>
); );

@ -163,6 +163,7 @@ export class DownPanelStore
@observable isTopToolBarShowMin: boolean = false; @observable isTopToolBarShowMin: boolean = false;
@observable isBottomToolBarShowMin: boolean = false; @observable isBottomToolBarShowMin: boolean = false;
@observable showHideSync: boolean = false; //显隐同步 @observable showHideSync: boolean = false; //显隐同步
@observable EnableSmartUCS: boolean = false; //智能UCS
private timeId; private timeId;
private constructor() private constructor()
{ {
@ -233,6 +234,7 @@ export class DownPanelStore
fontName: this.fontName, fontName: this.fontName,
lightsData: this.lightsData.map(l => l.enable), lightsData: this.lightsData.map(l => l.enable),
showHideSync: this.showHideSync, showHideSync: this.showHideSync,
smartUCS: this.EnableSmartUCS,
}; };
} }
async Upload() async Upload()
@ -314,6 +316,7 @@ export class DownPanelStore
this.SetSnapMode(); this.SetSnapMode();
this.showType = (this.isSmallScreen ? !this.isLeftToolBarShowMin : !this.isLeftToolBarShow) ? this.showType ^ ToolBarType.lefttoolbar : this.showType | ToolBarType.lefttoolbar; this.showType = (this.isSmallScreen ? !this.isLeftToolBarShowMin : !this.isLeftToolBarShow) ? this.showType ^ ToolBarType.lefttoolbar : this.showType | ToolBarType.lefttoolbar;
this.showHideSync = config.showHideSync ?? false; this.showHideSync = config.showHideSync ?? false;
this.EnableSmartUCS = config.smartUCS ?? false;
} }
toggleLeftToolBarShow() toggleLeftToolBarShow()

Loading…
Cancel
Save