abstract-3d 1.5.3 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -3
- package/lib/abstract-3d.d.ts +13 -1
- package/lib/abstract-3d.d.ts.map +1 -1
- package/lib/abstract-3d.js +7 -0
- package/lib/abstract-3d.js.map +1 -1
- package/lib/renderers/dxf/color.d.ts +1 -0
- package/lib/renderers/dxf/color.d.ts.map +1 -1
- package/lib/renderers/dxf/color.js +8 -0
- package/lib/renderers/dxf/color.js.map +1 -1
- package/lib/renderers/dxf/dxf-encoding.d.ts +2 -1
- package/lib/renderers/dxf/dxf-encoding.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf-encoding.js +13 -7
- package/lib/renderers/dxf/dxf-encoding.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-box.js +1 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-box.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.js +1 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-cone.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.js +1 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-cylinder.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-image.d.ts +4 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-image.d.ts.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-image.js +147 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-image.js.map +1 -0
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.js +1 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-plane.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.js +1 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-polygon.js.map +1 -1
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.js +1 -2
- package/lib/renderers/dxf/dxf-geometries/dxf-shape.js.map +1 -1
- package/lib/renderers/dxf/dxf.d.ts.map +1 -1
- package/lib/renderers/dxf/dxf.js +5 -0
- package/lib/renderers/dxf/dxf.js.map +1 -1
- package/lib/renderers/react/react-group.d.ts.map +1 -1
- package/lib/renderers/react/react-group.js +19 -1
- package/lib/renderers/react/react-group.js.map +1 -1
- package/lib/renderers/react/react-material.d.ts +1 -0
- package/lib/renderers/react/react-material.d.ts.map +1 -1
- package/lib/renderers/react/react-material.js +5 -1
- package/lib/renderers/react/react-material.js.map +1 -1
- package/lib/renderers/react/react-mesh.d.ts.map +1 -1
- package/lib/renderers/react/react-mesh.js +4 -0
- package/lib/renderers/react/react-mesh.js.map +1 -1
- package/lib/renderers/svg/svg-geometries/svg-image.d.ts +4 -0
- package/lib/renderers/svg/svg-geometries/svg-image.d.ts.map +1 -0
- package/lib/renderers/svg/svg-geometries/svg-image.js +27 -0
- package/lib/renderers/svg/svg-geometries/svg-image.js.map +1 -0
- package/lib/renderers/svg/svg.d.ts.map +1 -1
- package/lib/renderers/svg/svg.js +5 -3
- package/lib/renderers/svg/svg.js.map +1 -1
- package/package.json +3 -2
- package/src/.DS_Store +0 -0
- package/src/abstract-3d.ts +25 -1
- package/src/renderers/.DS_Store +0 -0
- package/src/renderers/dxf/color.ts +11 -1
- package/src/renderers/dxf/dxf-encoding.ts +15 -7
- package/src/renderers/dxf/dxf-geometries/dxf-box.ts +1 -1
- package/src/renderers/dxf/dxf-geometries/dxf-cone.ts +1 -1
- package/src/renderers/dxf/dxf-geometries/dxf-cylinder.ts +1 -1
- package/src/renderers/dxf/dxf-geometries/dxf-image.ts +177 -0
- package/src/renderers/dxf/dxf-geometries/dxf-plane.ts +1 -1
- package/src/renderers/dxf/dxf-geometries/dxf-polygon.ts +1 -1
- package/src/renderers/dxf/dxf-geometries/dxf-shape.ts +1 -1
- package/src/renderers/dxf/dxf.ts +6 -0
- package/src/renderers/react/react-group.tsx +22 -2
- package/src/renderers/react/react-material.tsx +7 -0
- package/src/renderers/react/react-mesh.tsx +13 -0
- package/src/renderers/svg/svg-geometries/svg-image.ts +44 -0
- package/src/renderers/svg/svg.ts +5 -3
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as AI from "abstract-image";
|
|
2
|
+
import { vec2Scale, vec3TransRot, vec3RotCombine, vec3Zero, vec3, } from "../../../abstract-3d.js";
|
|
3
|
+
import { zElem } from "./shared.js";
|
|
4
|
+
import { svgImage } from "../svg-encoding.js";
|
|
5
|
+
import { exhaustiveCheck } from "ts-exhaustive-check";
|
|
6
|
+
export function image(i, point, opts, parentPos, parentRot) {
|
|
7
|
+
const half = vec2Scale(i.size, 0.5);
|
|
8
|
+
const pos = vec3TransRot(i.pos, parentPos, parentRot);
|
|
9
|
+
const rot = vec3RotCombine(parentRot, i.rot ?? vec3Zero);
|
|
10
|
+
const vec3tr = (x, y) => vec3TransRot(vec3(x, y, 0), pos, rot);
|
|
11
|
+
const v2 = vec3tr(half.x, -half.y);
|
|
12
|
+
const v4 = vec3tr(-half.x, half.y);
|
|
13
|
+
switch (i.image.type) {
|
|
14
|
+
case "AbstractImage": {
|
|
15
|
+
const svg = AI.createSVG(i.image.image, opts);
|
|
16
|
+
const svgUrl = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
17
|
+
const img = svgImage(point(v4.x, v4.y), i.size, rot, {
|
|
18
|
+
type: "url",
|
|
19
|
+
url: svgUrl,
|
|
20
|
+
});
|
|
21
|
+
return [zElem(img, (v2.z + v4.z) / 2)];
|
|
22
|
+
}
|
|
23
|
+
default:
|
|
24
|
+
return exhaustiveCheck(i.image.type);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=svg-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-image.js","sourceRoot":"","sources":["../../../../src/renderers/svg/svg-geometries/svg-image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAIL,SAAS,EACT,YAAY,EACZ,cAAc,EACd,QAAQ,EACR,IAAI,GACL,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,EAA6B,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,MAAM,UAAU,KAAK,CACnB,CAAQ,EACR,KAAqC,EACrC,IAAgB,EAChB,SAAe,EACf,SAAe;IAEf,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,CAAS,EAAQ,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAErF,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAEnC,QAAO,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,eAAe,CAAC,CAAC,CAAC;YACrB,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG,sBAAsB,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE;gBACnD,IAAI,EAAE,KAAK;gBACX,GAAG,EAAE,MAAM;aACZ,CAAC,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzC,CAAC;QACD;YACE,OAAO,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../../src/renderers/svg/svg.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,EAQL,IAAI,EAaL,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAiB,MAAM,4BAA4B,CAAC;AASvE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["../../../src/renderers/svg/svg.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,EAQL,IAAI,EAaL,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAiB,MAAM,4BAA4B,CAAC;AASvE,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAIxC,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtG,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,WAAW,CAkB7G;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,WAAW,CAShF"}
|
package/lib/renderers/svg/svg.js
CHANGED
|
@@ -9,6 +9,7 @@ import { polygon } from "./svg-geometries/svg-polygon.js";
|
|
|
9
9
|
import { text } from "./svg-geometries/svg-text.js";
|
|
10
10
|
import { cone } from "./svg-geometries/svg-cone.js";
|
|
11
11
|
import { svg } from "./svg-encoding.js";
|
|
12
|
+
import { image } from "./svg-geometries/svg-image.js";
|
|
12
13
|
export function renderScenes(scenes, baseOptions) {
|
|
13
14
|
const allElements = Array();
|
|
14
15
|
const bounds = Array();
|
|
@@ -39,12 +40,11 @@ function renderInternal(scene, options, offset) {
|
|
|
39
40
|
imageDataByUrl: options?.imageDataByUrl ?? {},
|
|
40
41
|
rotation: options?.rotation ?? 0,
|
|
41
42
|
};
|
|
42
|
-
const
|
|
43
|
-
const baseRot = vec3RotCombine(viewRot, scene.rotation_deprecated ?? vec3Zero);
|
|
43
|
+
const baseRot = vec3RotCombine(rotationForCameraPos(opts.view), scene.rotation_deprecated ?? vec3Zero);
|
|
44
44
|
const unitRot = opts.rotation ? vec3RotCombine(vec3(0, 0, (opts.rotation * Math.PI) / 180), baseRot) : baseRot;
|
|
45
45
|
const [unitSize, unitCenter] = sizeCenterBoundsForCameraPos(scene.size_deprecated, scene.center_deprecated ?? vec3Zero, unitRot);
|
|
46
46
|
const svgSize = vec2(unitSize.x + 1.5 * opts.stroke_thickness, unitSize.y + 1.5 * opts.stroke_thickness);
|
|
47
|
-
const svgCenter = vec2(
|
|
47
|
+
const svgCenter = vec2(offset.x + opts.stroke_thickness * 0.75, offset.y + opts.stroke_thickness * 0.75);
|
|
48
48
|
const point = (x, y) => vec2(svgCenter.x + x, svgCenter.y - y);
|
|
49
49
|
const unitCenterFlipped = vec3Flip(unitCenter);
|
|
50
50
|
const elements = Array();
|
|
@@ -95,6 +95,8 @@ function svgMesh(mesh, parentPos, parentRot, point, material, opts) {
|
|
|
95
95
|
return shape(mesh.geometry, point, material, opts, parentPos, parentRot);
|
|
96
96
|
case "Text":
|
|
97
97
|
return text(mesh.geometry, point, material.normal, opts, parentPos, parentRot);
|
|
98
|
+
case "Image":
|
|
99
|
+
return image(mesh.geometry, point, opts, parentPos, parentRot);
|
|
98
100
|
case "Tube":
|
|
99
101
|
case "Sphere":
|
|
100
102
|
return [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"svg.js","sourceRoot":"","sources":["../../../src/renderers/svg/svg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EACL,IAAI,EAMJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,IAAI,EAGJ,YAAY,EAEZ,oBAAoB,EACpB,4BAA4B,EAE5B,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,QAAQ,EAER,QAAQ,GACT,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,GAAG,EAAE,MAAM,6BAA6B,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEpD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"svg.js","sourceRoot":"","sources":["../../../src/renderers/svg/svg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EACL,IAAI,EAMJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,IAAI,EAGJ,YAAY,EAEZ,oBAAoB,EACpB,4BAA4B,EAE5B,qBAAqB,EACrB,aAAa,EACb,YAAY,EACZ,QAAQ,EAER,QAAQ,GACT,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,GAAG,EAAE,MAAM,6BAA6B,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEpD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,+BAA+B,CAAC;AAUtD,MAAM,UAAU,YAAY,CAAC,MAA+B,EAAE,WAAkC;IAC9F,MAAM,WAAW,GAAG,KAAK,EAAiB,CAAC;IAC3C,MAAM,MAAM,GAAG,KAAK,EAAW,CAAC;IAEhC,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7G,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;QAC9B,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACtD,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,YAAY,GAAG,YAAY,CAAC,GAAG,MAAM,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,GAAG,CACf,YAAY,CAAC,GAAG,EAChB,IAAI,EACJ,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC,CAC9D,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAY,EAAE,OAA8B;IACjE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAE5E,MAAM,KAAK,GAAG,GAAG,CACf,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAClD,IAAI,EACJ,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,EAAE,EAAE,CAAC,CAC3D,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CACrB,KAAY,EACZ,OAAyC,EACzC,MAAY;IAMZ,MAAM,IAAI,GAAe;QACvB,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,OAAO;QAC9B,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,IAAI,CAAC;QAChD,WAAW,EAAE,OAAO,EAAE,WAAW,IAAI,KAAK;QAC1C,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,KAAK;QACxC,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,IAAI,qBAAqB;QACpE,IAAI,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE;QACzB,cAAc,EAAE,OAAO,EAAE,cAAc,IAAI,EAAE;QAC7C,QAAQ,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC;KACjC,CAAC;IACF,MAAM,OAAO,GAAG,cAAc,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,mBAAmB,IAAI,QAAQ,CAAC,CAAC;IACvG,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC/G,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,4BAA4B,CACzD,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,iBAAiB,IAAI,QAAQ,EACnC,OAAO,CACR,CAAC;IACF,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACzG,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACzG,MAAM,KAAK,GAAG,CAAC,CAAS,EAAE,CAAS,EAAQ,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrF,MAAM,iBAAiB,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAE/C,MAAM,QAAQ,GAAG,KAAK,EAAiB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,MAAM,OAAO,GAAe,EAAE,GAAG,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;IAC/E,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5D,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,qBAAqB,EAAE,UAAU,IAAI,EAAE,EAAE,CAAC;QAC9D,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;YACnD,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3C,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBACzB,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,qBAAqB,EAAE,QAAQ,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;YAClH,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,QAAQ,CACf,CAAQ,EACR,SAAe,EACf,SAAe,EACf,KAAqC,EACrC,IAAgB;IAEhB,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,KAAK,EAAiB,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAC/B,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,OAAO,CACd,IAAU,EACV,SAAe,EACf,SAAe,EACf,KAAqC,EACrC,QAAkB,EAClB,IAAgB;IAEhB,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC3B,KAAK,KAAK;YACR,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACzE,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3E,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC9E,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC1E,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACjF,KAAK,SAAS;YACZ,OAAO,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC7E,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QAC3E,KAAK,MAAM;YACT,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACjF,KAAK,OAAO;YACV,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;QACjE,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ;YACX,OAAO,EAAE,CAAC;QACZ;YACE,OAAO,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,MAAM,SAAS,GAAG,CAAC,CAAmB,EAAE,GAAS,EAAoB,EAAE;IACrE,QAAQ,CAAC,EAAE,CAAC;QACV,KAAK,OAAO;YACV,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QACtC,KAAK,MAAM;YACT,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QACtC,KAAK,MAAM;YACT,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACtC,KAAK,KAAK;YACR,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC;QACtC,KAAK,QAAQ;YACX,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;QACtC;YACE,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "abstract-3d",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Abstract 3D",
|
|
5
5
|
"author": "Divid AB <info@divid.se>",
|
|
6
6
|
"repository": "https://github.com/dividab/abstract-visuals/tree/master/packages/abstract-3d",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"@react-three/drei": "^10.7.6",
|
|
23
23
|
"@react-three/fiber": "^9.4.0",
|
|
24
24
|
"@react-three/postprocessing": "3.0.4",
|
|
25
|
+
"abstract-image": "^13.0.29",
|
|
25
26
|
"suspend-react": "^0.1.3",
|
|
26
27
|
"three": "^0.180.0",
|
|
27
28
|
"ts-exhaustive-check": "^1.0.0"
|
|
@@ -35,5 +36,5 @@
|
|
|
35
36
|
"@types/three": "^0.180.0",
|
|
36
37
|
"react": "^19.0.0"
|
|
37
38
|
},
|
|
38
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "83d19143f6848b9bd86a10c12d8bfea107f07f51"
|
|
39
40
|
}
|
package/src/.DS_Store
ADDED
|
Binary file
|
package/src/abstract-3d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import * as AI from "abstract-image";
|
|
1
2
|
import { Vector3 } from "three/src/math/Vector3.js";
|
|
2
3
|
import { Matrix4 } from "three/src/math/Matrix4.js";
|
|
3
4
|
import { Euler } from "three/src/math/Euler.js";
|
|
@@ -55,7 +56,7 @@ export type Group = {
|
|
|
55
56
|
|
|
56
57
|
export type Mesh = {
|
|
57
58
|
readonly material: Material;
|
|
58
|
-
readonly geometry: Cylinder | Cone | Box | Line | Text | Polygon | Plane | Tube | Sphere | Shape;
|
|
59
|
+
readonly geometry: Cylinder | Cone | Box | Line | Text | Polygon | Plane | Tube | Sphere | Shape | Image;
|
|
59
60
|
};
|
|
60
61
|
|
|
61
62
|
export type Material = {
|
|
@@ -66,6 +67,17 @@ export type Material = {
|
|
|
66
67
|
readonly imageUrl?: string;
|
|
67
68
|
};
|
|
68
69
|
|
|
70
|
+
export type Image = {
|
|
71
|
+
readonly type: "Image";
|
|
72
|
+
readonly pos: Vec3;
|
|
73
|
+
readonly rot?: Vec3;
|
|
74
|
+
readonly size: Vec2;
|
|
75
|
+
readonly image: {
|
|
76
|
+
readonly type: "AbstractImage",
|
|
77
|
+
readonly image: AI.AbstractImage,
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
69
81
|
export type Cylinder = {
|
|
70
82
|
readonly type: "Cylinder";
|
|
71
83
|
readonly pos: Vec3;
|
|
@@ -716,6 +728,18 @@ export const box = (
|
|
|
716
728
|
geometry: { type: "Box", pos, rot, size, holes },
|
|
717
729
|
material,
|
|
718
730
|
});
|
|
731
|
+
export const image = (
|
|
732
|
+
size: Vec3,
|
|
733
|
+
image: Image["image"],
|
|
734
|
+
pos: Vec3 = vec3Zero,
|
|
735
|
+
rot: Vec3 = vec3Zero,
|
|
736
|
+
): Image => ({
|
|
737
|
+
type: "Image",
|
|
738
|
+
image,
|
|
739
|
+
pos,
|
|
740
|
+
size,
|
|
741
|
+
rot,
|
|
742
|
+
});
|
|
719
743
|
|
|
720
744
|
export const roundHole = (pos: Vec2, radius: number): Hole => ({ type: "RoundHole", pos, radius });
|
|
721
745
|
export const squareHole = (pos: Vec2, size: Vec2): Hole => ({ type: "SquareHole", pos, size });
|
|
Binary file
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { Vec3, vec3, vec3DistSquared } from "../../abstract-3d.js";
|
|
2
2
|
|
|
3
|
+
export function colorToInteger(color: string): number {
|
|
4
|
+
const originalColor = colorNormalToVec3Color(color);
|
|
5
|
+
|
|
6
|
+
const colorAsInt = (originalColor.x << 16) + (originalColor.y << 8) + originalColor.z;
|
|
7
|
+
if(Number.isNaN(colorAsInt)) {
|
|
8
|
+
return 0;
|
|
9
|
+
}
|
|
10
|
+
return colorAsInt;
|
|
11
|
+
}
|
|
12
|
+
|
|
3
13
|
export function color(colorNormal: string | undefined): number {
|
|
4
14
|
const ERROR_COLOR = 6; //magenta
|
|
5
15
|
const ACI_COLOR_COUNT = 256;
|
|
@@ -22,7 +32,7 @@ export function color(colorNormal: string | undefined): number {
|
|
|
22
32
|
}
|
|
23
33
|
return closestColor;
|
|
24
34
|
}
|
|
25
|
-
|
|
35
|
+
|
|
26
36
|
function colorNormalToVec3Color(colorNormal: string): Vec3 {
|
|
27
37
|
const errorColor = vec3(255, 0, 255); // #ff00ff, magenta
|
|
28
38
|
const paranthesisRegex = /(?<=\().+?(?=\))/;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable max-lines */
|
|
2
2
|
import { Vec3 } from "../../abstract-3d.js";
|
|
3
3
|
import { generateUUID } from "three/src/math/MathUtils.js";
|
|
4
|
+
import { colorToInteger } from "./color.js";
|
|
4
5
|
|
|
5
6
|
export type DxfOrigin = "BottomLeftFront" | "Center";
|
|
6
7
|
|
|
@@ -11,7 +12,7 @@ export function dxf(groups: string, center: Vec3, size: Vec3, origin: DxfOrigin)
|
|
|
11
12
|
|
|
12
13
|
export type Handle = { handle: number };
|
|
13
14
|
|
|
14
|
-
function dxfHandle(handleRef: Handle): string {
|
|
15
|
+
export function dxfHandle(handleRef: Handle): string {
|
|
15
16
|
return (++handleRef.handle).toString(16).toUpperCase();
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -25,18 +26,25 @@ export const dxf3DFACE = (
|
|
|
25
26
|
vec2: Vec3,
|
|
26
27
|
vec3: Vec3,
|
|
27
28
|
vec4: Vec3,
|
|
28
|
-
|
|
29
|
+
col: string | 7,
|
|
29
30
|
handleRef: Handle
|
|
30
31
|
): string => ` 0
|
|
31
32
|
3DFACE
|
|
32
|
-
|
|
33
|
+
5
|
|
33
34
|
${dxfHandle(handleRef)}
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
330
|
|
36
|
+
1D
|
|
36
37
|
100
|
|
37
38
|
AcDbEntity
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
${
|
|
40
|
+
typeof col === "number" ?
|
|
41
|
+
`62\n7`
|
|
42
|
+
:
|
|
43
|
+
`62
|
|
44
|
+
256
|
|
45
|
+
420
|
|
46
|
+
${colorToInteger(col)}`
|
|
47
|
+
}
|
|
40
48
|
100
|
|
41
49
|
AcDbFace
|
|
42
50
|
10
|
|
@@ -16,7 +16,7 @@ export function dxfBox(b: Box, m: Material, parentPos: Vec3, parentRot: Vec3, ha
|
|
|
16
16
|
const v6 = vec3tr3(half.x, -half.y, -half.z);
|
|
17
17
|
const v7 = vec3tr3(half.x, half.y, -half.z);
|
|
18
18
|
const v8 = vec3tr3(-half.x, half.y, -half.z);
|
|
19
|
-
const mat =
|
|
19
|
+
const mat = m.normal;
|
|
20
20
|
return (
|
|
21
21
|
dxf3DFACE(v1, v2, v3, v4, mat, handleRef) + // front
|
|
22
22
|
dxf3DFACE(v5, v6, v7, v8, mat, handleRef) + // Back
|
|
@@ -14,7 +14,7 @@ export function dxfCone(
|
|
|
14
14
|
const pos = vec3TransRot(c.pos, parentPos, parentRot);
|
|
15
15
|
const rot = vec3RotCombine(parentRot, c.rot ?? vec3Zero);
|
|
16
16
|
const vec3tr2 = (x: number, y: number, z: number): Vec3 => vec3TransRot(vec3(x, y, z), pos, rot);
|
|
17
|
-
const mat =
|
|
17
|
+
const mat = m.normal;
|
|
18
18
|
const angleStep = (2 * Math.PI) / sides;
|
|
19
19
|
let currentAngle = 0;
|
|
20
20
|
|
|
@@ -28,7 +28,7 @@ export function dxfCylinder(
|
|
|
28
28
|
const pos = vec3TransRot(c.pos, parentPos, parentRot);
|
|
29
29
|
const rot = vec3RotCombine(parentRot, c.rot ?? vec3Zero);
|
|
30
30
|
const vec3tr = (x: number, y: number, z: number): Vec3 => vec3TransRot(vec3(x, y, z), pos, rot);
|
|
31
|
-
const mat =
|
|
31
|
+
const mat = m.normal;
|
|
32
32
|
const angleStep = angleLength / sides;
|
|
33
33
|
let currentAngle = angleStart;
|
|
34
34
|
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import * as AI from "abstract-image";
|
|
2
|
+
import {
|
|
3
|
+
Image,
|
|
4
|
+
Vec3,
|
|
5
|
+
vec2Scale,
|
|
6
|
+
vec3TransRot,
|
|
7
|
+
vec3RotCombine,
|
|
8
|
+
vec3Zero,
|
|
9
|
+
vec3,
|
|
10
|
+
vec3Rot,
|
|
11
|
+
vec3Add,
|
|
12
|
+
vec3Sub,
|
|
13
|
+
vec3Normalize,
|
|
14
|
+
vec3Cross,
|
|
15
|
+
vec3Scale,
|
|
16
|
+
} from "../../../abstract-3d.js";
|
|
17
|
+
import { dxf3DFACE, dxfHandle, Handle } from "../dxf-encoding.js";
|
|
18
|
+
import { dxfPlane } from "./dxf-plane.js";
|
|
19
|
+
|
|
20
|
+
export function dxfImage(i: Image, parentPos: Vec3, parentRot: Vec3, handleRef: Handle): string {
|
|
21
|
+
|
|
22
|
+
const half = vec2Scale(i.size, 0.5);
|
|
23
|
+
const offset = vec3Rot(vec3(-half.x, half.y, 0), vec3Zero, i.rot ?? vec3Zero);
|
|
24
|
+
const pos = vec3TransRot(vec3Add(i.pos, offset), parentPos, parentRot);
|
|
25
|
+
const rot = vec3RotCombine(parentRot, i.rot ?? vec3Zero);
|
|
26
|
+
|
|
27
|
+
switch(i.image.type) {
|
|
28
|
+
case "AbstractImage": {
|
|
29
|
+
const scale = {
|
|
30
|
+
x: i.size.x / i.image.image.size.width,
|
|
31
|
+
y: -i.size.y / i.image.image.size.height,
|
|
32
|
+
z: 1,
|
|
33
|
+
};
|
|
34
|
+
return abstractImageToDxf3D(i.image.image, pos, rot, scale, handleRef);
|
|
35
|
+
}
|
|
36
|
+
default:
|
|
37
|
+
return "";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function abstractImageToDxf3D(image: AI.AbstractImage, pos: Vec3, rot: Vec3, scale: Vec3, handleRef: Handle): string {
|
|
42
|
+
const strokeScale = Math.max(scale.x, scale.y, scale.z);
|
|
43
|
+
|
|
44
|
+
let dxf = "";
|
|
45
|
+
|
|
46
|
+
//create the background and place it slightly below the stroke elements
|
|
47
|
+
// const normal = eulerToVector(rot);
|
|
48
|
+
// const bgSize = { x: image.size.width * scale.x, y: image.size.height * scale.y, z: 1 };
|
|
49
|
+
// const bgHalf = vec3Rot(vec3Scale(bgSize, 0.5), vec3Zero, rot);
|
|
50
|
+
// const bgPos = vec3Add(vec3Add(pos, bgHalf), vec3Scale(normal, -1));
|
|
51
|
+
// dxf += dxfPlane({
|
|
52
|
+
// type: "Plane",
|
|
53
|
+
// size: bgSize,
|
|
54
|
+
// pos: bgPos,
|
|
55
|
+
// rot,
|
|
56
|
+
// }, {normal: `normal(0, 0, 1)`}, vec3Zero, vec3Zero, handleRef);
|
|
57
|
+
|
|
58
|
+
for(const comp of image.components) {
|
|
59
|
+
dxf += abstractImageComponentToDxf3D(comp, pos, rot, scale, strokeScale, handleRef);
|
|
60
|
+
}
|
|
61
|
+
return dxf;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function abstractImageComponentToDxf3D(comp: AI.Component, pos: Vec3, rot: Vec3, scale: Vec3, strokeScale: number, handleRef: Handle): string {
|
|
65
|
+
const vec3tr = (x: number, y: number): Vec3 => vec3TransRot(vec3(x * scale.x, y * scale.y, 0), pos, rot);
|
|
66
|
+
const strokeColor: AI.Color = { a: 255.0, r: 0.0, g: 0.0, b: 0.0 };
|
|
67
|
+
|
|
68
|
+
let dxf = "";
|
|
69
|
+
switch(comp.type) {
|
|
70
|
+
case "group": {
|
|
71
|
+
for(const child of comp.children) {
|
|
72
|
+
dxf += abstractImageComponentToDxf3D(child, pos, rot, scale, strokeScale, handleRef);
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case "line": {
|
|
77
|
+
dxf += dxfLine(vec3tr(comp.start.x, comp.start.y), vec3tr(comp.end.x, comp.end.y), strokeColor, comp.strokeThickness * strokeScale, rot, handleRef);
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
case "polyline": {
|
|
81
|
+
const points = comp.points.map((p) => vec3tr(p.x, p.y));
|
|
82
|
+
dxf += dxfPolyline(points, strokeColor, false, comp.strokeThickness * strokeScale, rot, handleRef);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
case "polygon": {
|
|
86
|
+
const points = comp.points.map((p) => vec3tr(p.x, p.y));
|
|
87
|
+
dxf += dxfPolyline(points, strokeColor, true, comp.strokeThickness * strokeScale, rot, handleRef);
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case "ellipse": {
|
|
91
|
+
const points: Array<Vec3> = [];
|
|
92
|
+
const r1 = Math.abs(comp.bottomRight.x - comp.topLeft.x) / 2.0;
|
|
93
|
+
const r2 = Math.abs(comp.topLeft.y - comp.bottomRight.y) / 2.0;
|
|
94
|
+
const numPoints = 32;
|
|
95
|
+
for (let i = 0; i < numPoints; i++) {
|
|
96
|
+
const t = (2 * Math.PI * i) / numPoints;
|
|
97
|
+
const x = comp.topLeft.x + r1 + r1 * Math.cos(t);
|
|
98
|
+
const y = comp.topLeft.y + r2 + r2 * Math.sin(t);
|
|
99
|
+
points.push(vec3tr(x, y));
|
|
100
|
+
}
|
|
101
|
+
dxf += dxfPolyline(points, strokeColor, true, comp.strokeThickness * strokeScale, rot, handleRef);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "rectangle": {
|
|
105
|
+
const size = {
|
|
106
|
+
x: comp.bottomRight.x - comp.topLeft.x,
|
|
107
|
+
y: comp.bottomRight.y - comp.topLeft.y
|
|
108
|
+
};
|
|
109
|
+
const points = [
|
|
110
|
+
vec3tr(0, 0),
|
|
111
|
+
vec3tr(size.x, 0),
|
|
112
|
+
vec3tr(size.x, size.y),
|
|
113
|
+
vec3tr(0, size.y),
|
|
114
|
+
];
|
|
115
|
+
dxf += dxfPolyline(points, strokeColor, true, comp.strokeThickness * strokeScale, rot, handleRef);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
default:
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return dxf;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function dxfLine(vecStart: Vec3, vecEnd: Vec3, color: AI.Color, strokeThickness: number, normal: Vec3, handleRef: Handle): string {
|
|
126
|
+
const norm = eulerToVector(normal);
|
|
127
|
+
strokeThickness = 0;
|
|
128
|
+
|
|
129
|
+
const dir = vec3Normalize(vec3Sub(vecEnd, vecStart));
|
|
130
|
+
const right = vec3Cross(dir, norm);
|
|
131
|
+
const s1 = vec3Add(vecStart, vec3Scale(right, strokeThickness / 2));
|
|
132
|
+
const s2 = vec3Add(vecStart, vec3Scale(right, -strokeThickness / 2));
|
|
133
|
+
const e1 = vec3Add(vecEnd, vec3Scale(right, strokeThickness / 2));
|
|
134
|
+
const e2 = vec3Add(vecEnd, vec3Scale(right, -strokeThickness / 2));
|
|
135
|
+
//return dxf3DFACE(s1, e1, e2, s2, abstractImageColorToHex(color), handleRef);
|
|
136
|
+
return dxf3DFACE(s1, e1, e2, s2, 7, handleRef);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function dxfPolyline(points: ReadonlyArray<Vec3>, color: AI.Color, closed: boolean, strokeThickness: number, normal: Vec3, handleRef: Handle): string {
|
|
140
|
+
let dxf = "";
|
|
141
|
+
for(let i = 0; i < points.length - 1; i++) {
|
|
142
|
+
const p1 = points[i];
|
|
143
|
+
const p2 = points[i+1];
|
|
144
|
+
if(!p1 || !p2) {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
dxf += dxfLine(p1, p2, color, strokeThickness, normal, handleRef);
|
|
148
|
+
}
|
|
149
|
+
if(closed) {
|
|
150
|
+
const start = points[0];
|
|
151
|
+
const end = points[points.length - 1];
|
|
152
|
+
if(start && end) {
|
|
153
|
+
dxf += dxfLine(start, end, color, strokeThickness, normal, handleRef);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return dxf;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function abstractImageColorToHex(color: AI.Color): string {
|
|
160
|
+
const col = `rgb(${color.r}, ${color.g}, ${color.b})`;
|
|
161
|
+
return col;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function eulerToVector(euler: Vec3): Vec3 {
|
|
165
|
+
const cx = Math.cos(euler.x);
|
|
166
|
+
const sx = Math.sin(euler.x);
|
|
167
|
+
const cy = Math.cos(euler.y);
|
|
168
|
+
const sy = Math.sin(euler.y);
|
|
169
|
+
//const cz = Math.cos(euler.z); ?
|
|
170
|
+
//const sz = Math.sin(euler.z); ?
|
|
171
|
+
const norm = {
|
|
172
|
+
x: sy,
|
|
173
|
+
y: -sx * cy,
|
|
174
|
+
z: cx * cy
|
|
175
|
+
};
|
|
176
|
+
return norm;
|
|
177
|
+
}
|
|
@@ -7,7 +7,7 @@ const TRIANGLE_STRIDE = 3;
|
|
|
7
7
|
|
|
8
8
|
export function dxfPolygon(p: Polygon, m: Material, parentPos: Vec3, parentRot: Vec3, handleRef: Handle): string {
|
|
9
9
|
let polygonString = "";
|
|
10
|
-
const col =
|
|
10
|
+
const col = m.normal;
|
|
11
11
|
const pos = vec3TransRot(p.pos, parentPos, parentRot);
|
|
12
12
|
const rot = vec3RotCombine(parentRot, p.rot ?? vec3Zero);
|
|
13
13
|
const points = p.points.map((p) => vec3TransRot(p, pos, rot));
|
|
@@ -9,7 +9,7 @@ export function dxfPolygon(s: Shape, m: Material, parentPos: Vec3, parentRot: Ve
|
|
|
9
9
|
const pos = vec3TransRot(s.pos, parentPos, parentRot);
|
|
10
10
|
const rot = vec3RotCombine(parentRot, s.rot ?? vec3Zero);
|
|
11
11
|
const points = s.points.map((p) => vec3TransRot(vec3(p.x, p.y, 0), pos, rot));
|
|
12
|
-
const mat =
|
|
12
|
+
const mat = m.normal;
|
|
13
13
|
let i = 0;
|
|
14
14
|
if (points.length >= chunkSize) {
|
|
15
15
|
for (i; i < points.length; i += chunkSize) {
|
package/src/renderers/dxf/dxf.ts
CHANGED
|
@@ -24,6 +24,7 @@ import { dxfCylinder } from "./dxf-geometries/dxf-cylinder.js";
|
|
|
24
24
|
import { dxfCone } from "./dxf-geometries/dxf-cone.js";
|
|
25
25
|
import { dxfPolygon } from "./dxf-geometries/dxf-polygon.js";
|
|
26
26
|
import { Optional } from "../shared.js";
|
|
27
|
+
import { dxfImage } from "./dxf-geometries/dxf-image.js";
|
|
27
28
|
|
|
28
29
|
const DEFAULT_CYLINDER_SIDE_COUNT = 18;
|
|
29
30
|
|
|
@@ -67,6 +68,7 @@ const renderInternal = (
|
|
|
67
68
|
scene.center_deprecated ?? vec3Zero,
|
|
68
69
|
unitRot
|
|
69
70
|
);
|
|
71
|
+
|
|
70
72
|
// const unitCenterFlipped = vec3Flip(center);
|
|
71
73
|
const dxfCenter = vec3Add(center, offset);
|
|
72
74
|
return {
|
|
@@ -103,6 +105,10 @@ function dxfGroup(g: Group, parentPos: Vec3, parentRot: Vec3, options: DxfOption
|
|
|
103
105
|
dxf += dxfPolygon(mesh.geometry, mesh.material, pos, rot, handleRef);
|
|
104
106
|
break;
|
|
105
107
|
}
|
|
108
|
+
case "Image": {
|
|
109
|
+
dxf += dxfImage(mesh.geometry, pos, rot, handleRef);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
106
112
|
default:
|
|
107
113
|
break;
|
|
108
114
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import * as AI from "abstract-image";
|
|
2
3
|
import { ThreeEvent, useFrame } from "@react-three/fiber";
|
|
3
4
|
import type { Group } from "three";
|
|
4
|
-
import { Group as Group_1 } from "../../abstract-3d.js";
|
|
5
|
+
import { Group as Group_1, Material, Mesh } from "../../abstract-3d.js";
|
|
5
6
|
import { MaterialState, ReactMaterial } from "./react-material.js";
|
|
6
7
|
import { ReactMesh } from "./react-mesh.js";
|
|
7
8
|
|
|
@@ -128,7 +129,7 @@ export function ReactGroup({
|
|
|
128
129
|
{g.meshes?.map((m, i) => (
|
|
129
130
|
<ReactMesh key={`mesh_${i}`} mesh={m}>
|
|
130
131
|
<ReactMaterial
|
|
131
|
-
material={m
|
|
132
|
+
material={getMaterial(m)}
|
|
132
133
|
id={id}
|
|
133
134
|
selectedIds={selectedIds}
|
|
134
135
|
isText={m.geometry.type === "Text"}
|
|
@@ -143,3 +144,22 @@ export function ReactGroup({
|
|
|
143
144
|
</group>
|
|
144
145
|
);
|
|
145
146
|
}
|
|
147
|
+
|
|
148
|
+
function getMaterial(mesh: Mesh): Material {
|
|
149
|
+
if(mesh.geometry.type !== "Image") {
|
|
150
|
+
return mesh.material;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
switch(mesh.geometry.image.type) {
|
|
154
|
+
case "AbstractImage": {
|
|
155
|
+
const svg = AI.createSVG(mesh.geometry.image.image);
|
|
156
|
+
const svgUrl = `data:image/svg+xml,${svg}`;
|
|
157
|
+
return {
|
|
158
|
+
...mesh.material,
|
|
159
|
+
imageUrl: svgUrl,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
default:
|
|
163
|
+
return mesh.material;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -14,6 +14,7 @@ import { shade } from "../shared.js";
|
|
|
14
14
|
|
|
15
15
|
const decreasedOpacity = 0.125;
|
|
16
16
|
|
|
17
|
+
export type TextureFilter = "Nearest" | "Linear";
|
|
17
18
|
export type MaterialState = "Accept" | "Error" | "Warning";
|
|
18
19
|
export const ERROR_IMG_KEY = "error";
|
|
19
20
|
|
|
@@ -124,11 +125,13 @@ function TextureMaterial({
|
|
|
124
125
|
color,
|
|
125
126
|
material,
|
|
126
127
|
useAlphaTest = true,
|
|
128
|
+
filter = "Linear"
|
|
127
129
|
}: {
|
|
128
130
|
readonly url: string;
|
|
129
131
|
readonly color: string | Color | undefined;
|
|
130
132
|
readonly material: Material;
|
|
131
133
|
readonly useAlphaTest?: boolean;
|
|
134
|
+
readonly filter?: TextureFilter;
|
|
132
135
|
}): React.JSX.Element {
|
|
133
136
|
const texture = suspend(
|
|
134
137
|
new Promise((res) =>
|
|
@@ -136,6 +139,10 @@ function TextureMaterial({
|
|
|
136
139
|
url,
|
|
137
140
|
(data) => {
|
|
138
141
|
data.colorSpace = SRGBColorSpace;
|
|
142
|
+
if(filter === "Nearest") {
|
|
143
|
+
data.minFilter = 1003;
|
|
144
|
+
data.magFilter = 1003;
|
|
145
|
+
}
|
|
139
146
|
res(data);
|
|
140
147
|
},
|
|
141
148
|
undefined,
|
|
@@ -188,6 +188,19 @@ export function ReactMesh({
|
|
|
188
188
|
);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
191
|
+
case "Image": {
|
|
192
|
+
const { pos, size, rot } = mesh.geometry;
|
|
193
|
+
return <mesh
|
|
194
|
+
geometry={planeGeometry}
|
|
195
|
+
scale={[size.x, size.y, 1]}
|
|
196
|
+
position={[pos.x, pos.y, pos.z]}
|
|
197
|
+
rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
|
|
198
|
+
castShadow
|
|
199
|
+
receiveShadow
|
|
200
|
+
>
|
|
201
|
+
{children}
|
|
202
|
+
</mesh>;
|
|
203
|
+
}
|
|
191
204
|
case "Plane": {
|
|
192
205
|
const { pos, size, rot, holes } = mesh.geometry;
|
|
193
206
|
const filteredHoles = holes?.filter((h) => !holeIsZero(h));
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import * as AI from "abstract-image";
|
|
2
|
+
import {
|
|
3
|
+
Image,
|
|
4
|
+
Vec2,
|
|
5
|
+
Vec3,
|
|
6
|
+
vec2Scale,
|
|
7
|
+
vec3TransRot,
|
|
8
|
+
vec3RotCombine,
|
|
9
|
+
vec3Zero,
|
|
10
|
+
vec3,
|
|
11
|
+
} from "../../../abstract-3d.js";
|
|
12
|
+
import { zElem, zOrderElement, SvgOptions } from "./shared.js";
|
|
13
|
+
import { svgImage } from "../svg-encoding.js";
|
|
14
|
+
import { exhaustiveCheck } from "ts-exhaustive-check";
|
|
15
|
+
|
|
16
|
+
export function image(
|
|
17
|
+
i: Image,
|
|
18
|
+
point: (x: number, y: number) => Vec2,
|
|
19
|
+
opts: SvgOptions,
|
|
20
|
+
parentPos: Vec3,
|
|
21
|
+
parentRot: Vec3,
|
|
22
|
+
): ReadonlyArray<zOrderElement> {
|
|
23
|
+
const half = vec2Scale(i.size, 0.5);
|
|
24
|
+
const pos = vec3TransRot(i.pos, parentPos, parentRot);
|
|
25
|
+
const rot = vec3RotCombine(parentRot, i.rot ?? vec3Zero);
|
|
26
|
+
const vec3tr = (x: number, y: number): Vec3 => vec3TransRot(vec3(x, y, 0), pos, rot);
|
|
27
|
+
|
|
28
|
+
const v2 = vec3tr(half.x, -half.y);
|
|
29
|
+
const v4 = vec3tr(-half.x, half.y);
|
|
30
|
+
|
|
31
|
+
switch(i.image.type) {
|
|
32
|
+
case "AbstractImage": {
|
|
33
|
+
const svg = AI.createSVG(i.image.image, opts);
|
|
34
|
+
const svgUrl = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
35
|
+
const img = svgImage(point(v4.x, v4.y), i.size, rot, {
|
|
36
|
+
type: "url",
|
|
37
|
+
url: svgUrl,
|
|
38
|
+
});
|
|
39
|
+
return [zElem(img, (v2.z + v4.z) / 2)];
|
|
40
|
+
}
|
|
41
|
+
default:
|
|
42
|
+
return exhaustiveCheck(i.image.type);
|
|
43
|
+
}
|
|
44
|
+
}
|