gltf-parser-plugin 1.1.9 → 1.1.10
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.
|
@@ -393,44 +393,48 @@ var MeshCollector = class extends EventDispatcher {
|
|
|
393
393
|
//#endregion
|
|
394
394
|
//#region src/plugin/style-condition-eval.ts
|
|
395
395
|
/**
|
|
396
|
-
*
|
|
397
|
-
* 在 propertyData 的键作为变量名的上下文中执行 `Boolean(expr)`
|
|
398
|
-
*
|
|
399
|
-
* 实现:对每个表达式字符串只编译一次 `new Function('data', 'with(d){...}')`,
|
|
400
|
-
* 避免按「表达式 × 属性键集合」重复编译,也避免每次求值排序/拼接 cacheKey。
|
|
396
|
+
* 编译单个表达式;失败返回 null(无模块级缓存)
|
|
401
397
|
*/
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
let fn = compiledCache.get(expr);
|
|
406
|
-
if (fn) return fn;
|
|
398
|
+
function compileStyleCondition(expr) {
|
|
399
|
+
const trimmed = expr.trim();
|
|
400
|
+
if (!trimmed) return null;
|
|
407
401
|
try {
|
|
408
|
-
|
|
409
|
-
with (d) { return Boolean(${
|
|
402
|
+
return new Function("data", `var d = data != null && typeof data === "object" ? data : {};
|
|
403
|
+
with (d) { return Boolean(${trimmed}); }`);
|
|
410
404
|
} catch {
|
|
411
405
|
return null;
|
|
412
406
|
}
|
|
413
|
-
if (compiledCache.size >= MAX_CACHE_ENTRIES) {
|
|
414
|
-
const first = compiledCache.keys().next().value;
|
|
415
|
-
if (first !== void 0) compiledCache.delete(first);
|
|
416
|
-
}
|
|
417
|
-
compiledCache.set(expr, fn);
|
|
418
|
-
return fn;
|
|
419
407
|
}
|
|
420
408
|
/**
|
|
421
|
-
*
|
|
409
|
+
* 遍历 style 的 show 与 conditions,对每个出现过的字符串表达式只编译一次
|
|
422
410
|
*/
|
|
423
|
-
function
|
|
424
|
-
|
|
411
|
+
function buildStyleConditionEvaluatorMap(config) {
|
|
412
|
+
const strings = /* @__PURE__ */ new Set();
|
|
413
|
+
if (config.show?.trim()) strings.add(config.show.trim());
|
|
414
|
+
for (const [cond] of config.conditions ?? []) if (typeof cond === "string" && cond.trim()) strings.add(cond.trim());
|
|
415
|
+
const map = /* @__PURE__ */ new Map();
|
|
416
|
+
for (const s of strings) {
|
|
417
|
+
const fn = compileStyleCondition(s);
|
|
418
|
+
if (fn) map.set(s, fn);
|
|
419
|
+
}
|
|
420
|
+
return map;
|
|
425
421
|
}
|
|
426
|
-
function evaluateStyleCondition(expr, propertyData) {
|
|
422
|
+
function evaluateStyleCondition(expr, propertyData, evaluators) {
|
|
427
423
|
if (expr === true) return true;
|
|
428
424
|
if (expr === false) return false;
|
|
429
425
|
if (typeof expr !== "string" || !expr.trim()) return true;
|
|
430
|
-
const
|
|
426
|
+
const trimmed = expr.trim();
|
|
427
|
+
const data = propertyData ?? {};
|
|
428
|
+
const fromMap = evaluators?.get(trimmed);
|
|
429
|
+
if (fromMap) try {
|
|
430
|
+
return fromMap(data);
|
|
431
|
+
} catch {
|
|
432
|
+
return false;
|
|
433
|
+
}
|
|
434
|
+
const fn = compileStyleCondition(trimmed);
|
|
431
435
|
if (!fn) return false;
|
|
432
436
|
try {
|
|
433
|
-
return fn(
|
|
437
|
+
return fn(data);
|
|
434
438
|
} catch {
|
|
435
439
|
return false;
|
|
436
440
|
}
|
|
@@ -2625,6 +2629,36 @@ var PartFrameHelper = class {
|
|
|
2625
2629
|
};
|
|
2626
2630
|
//#endregion
|
|
2627
2631
|
//#region src/plugin/style-appearance-shared.ts
|
|
2632
|
+
var fnIdentitySeq = /* @__PURE__ */ new WeakMap();
|
|
2633
|
+
var fnIdentityNext = 1;
|
|
2634
|
+
function styleFnIdentity(fn) {
|
|
2635
|
+
let id = fnIdentitySeq.get(fn);
|
|
2636
|
+
if (id === void 0) {
|
|
2637
|
+
id = fnIdentityNext++;
|
|
2638
|
+
fnIdentitySeq.set(fn, id);
|
|
2639
|
+
}
|
|
2640
|
+
return id;
|
|
2641
|
+
}
|
|
2642
|
+
/** 从构件材质提取贴图,供 material 回调使用 */
|
|
2643
|
+
function extractStyleMaterialMaps(material) {
|
|
2644
|
+
const m = material;
|
|
2645
|
+
const tex = (key) => {
|
|
2646
|
+
const v = m[key];
|
|
2647
|
+
return v && typeof v === "object" && "isTexture" in v && v.isTexture ? v : null;
|
|
2648
|
+
};
|
|
2649
|
+
return {
|
|
2650
|
+
map: tex("map"),
|
|
2651
|
+
normalMap: tex("normalMap"),
|
|
2652
|
+
metalnessMap: tex("metalnessMap"),
|
|
2653
|
+
roughnessMap: tex("roughnessMap"),
|
|
2654
|
+
aoMap: tex("aoMap"),
|
|
2655
|
+
emissiveMap: tex("emissiveMap")
|
|
2656
|
+
};
|
|
2657
|
+
}
|
|
2658
|
+
function resolveStyleMaterial(appearance, originalMaterial) {
|
|
2659
|
+
if (typeof appearance.material === "function") return appearance.material(extractStyleMaterialMaps(originalMaterial));
|
|
2660
|
+
return appearance.material;
|
|
2661
|
+
}
|
|
2628
2662
|
function vec3Key(v) {
|
|
2629
2663
|
if (v === void 0) return "";
|
|
2630
2664
|
if (Array.isArray(v)) return `${v[0] ?? 0},${v[1] ?? 0},${v[2] ?? 0}`;
|
|
@@ -2647,7 +2681,7 @@ function applyEuler(target, input) {
|
|
|
2647
2681
|
else target.copy(input);
|
|
2648
2682
|
}
|
|
2649
2683
|
function appearanceGroupKey(a) {
|
|
2650
|
-
return `${a.material.uuid}|${vec3Key(a.translation)}|${vec3Key(a.scale)}|${eulerKey(a.rotation)}|${vec3Key(a.origin)}`;
|
|
2684
|
+
return `${typeof a.material === "function" ? `matFn#${styleFnIdentity(a.material)}` : a.material.uuid}${a.mesh ? `|meshFn#${styleFnIdentity(a.mesh)}` : ""}|${vec3Key(a.translation)}|${vec3Key(a.scale)}|${eulerKey(a.rotation)}|${vec3Key(a.origin)}`;
|
|
2651
2685
|
}
|
|
2652
2686
|
function buildPivotStyleMatrix(pivot, sx, sy, sz, euler) {
|
|
2653
2687
|
const m = new Matrix4().makeTranslation(-pivot.x, -pivot.y, -pivot.z);
|
|
@@ -2656,28 +2690,25 @@ function buildPivotStyleMatrix(pivot, sx, sy, sz, euler) {
|
|
|
2656
2690
|
m.premultiply(new Matrix4().makeTranslation(pivot.x, pivot.y, pivot.z));
|
|
2657
2691
|
return m;
|
|
2658
2692
|
}
|
|
2659
|
-
function resolveConditionsAppearance(conditions, propertyData) {
|
|
2693
|
+
function resolveConditionsAppearance(conditions, propertyData, evaluators) {
|
|
2660
2694
|
if (!conditions?.length) return null;
|
|
2661
|
-
for (const [cond, value] of conditions) if (evaluateStyleCondition(cond, propertyData)) return value;
|
|
2695
|
+
for (const [cond, value] of conditions) if (evaluateStyleCondition(cond, propertyData, evaluators)) return value;
|
|
2662
2696
|
return null;
|
|
2663
2697
|
}
|
|
2664
|
-
function resolveStyleAppearance(conditions, propertyData) {
|
|
2665
|
-
return resolveConditionsAppearance(conditions, propertyData);
|
|
2666
|
-
}
|
|
2667
2698
|
/** 与 setStyle 相同的 OID 分组逻辑(show + conditions → 外观分组 + 被 show 隐藏的 OID) */
|
|
2668
|
-
function buildAppearanceGroupsFromPropertyMap(propertyByOid, config) {
|
|
2699
|
+
function buildAppearanceGroupsFromPropertyMap(propertyByOid, config, evaluators) {
|
|
2669
2700
|
const hiddenOidsList = [];
|
|
2670
2701
|
const groups = /* @__PURE__ */ new Map();
|
|
2671
2702
|
const conditions = config.conditions ?? [];
|
|
2672
2703
|
for (const [oid, propertyData] of propertyByOid) {
|
|
2673
2704
|
if (propertyData == null) continue;
|
|
2674
2705
|
if (config.show) {
|
|
2675
|
-
if (!evaluateStyleCondition(config.show, propertyData)) {
|
|
2706
|
+
if (!evaluateStyleCondition(config.show, propertyData, evaluators)) {
|
|
2676
2707
|
hiddenOidsList.push(oid);
|
|
2677
2708
|
continue;
|
|
2678
2709
|
}
|
|
2679
2710
|
}
|
|
2680
|
-
const appearance =
|
|
2711
|
+
const appearance = resolveConditionsAppearance(conditions, propertyData, evaluators);
|
|
2681
2712
|
if (!appearance) continue;
|
|
2682
2713
|
const gkey = appearanceGroupKey(appearance);
|
|
2683
2714
|
let g = groups.get(gkey);
|
|
@@ -2714,7 +2745,9 @@ function restoreMeshAppearanceMaps(mesh, maps) {
|
|
|
2714
2745
|
*/
|
|
2715
2746
|
function applyStyleAppearanceToMesh(mesh, appearance, scene, maps) {
|
|
2716
2747
|
if (!maps.originalMaterialByMesh.has(mesh.uuid)) maps.originalMaterialByMesh.set(mesh.uuid, mesh.material);
|
|
2717
|
-
|
|
2748
|
+
const resolvedMaterial = resolveStyleMaterial(appearance, maps.originalMaterialByMesh.get(mesh.uuid));
|
|
2749
|
+
if (appearance.mesh) mesh = appearance.mesh(mesh.geometry, resolvedMaterial);
|
|
2750
|
+
else mesh.material = resolvedMaterial;
|
|
2718
2751
|
if (appearance.translation !== void 0 || appearance.scale !== void 0 || appearance.rotation !== void 0) {
|
|
2719
2752
|
if (!maps.originalTransformByMesh.has(mesh.uuid)) maps.originalTransformByMesh.set(mesh.uuid, {
|
|
2720
2753
|
position: mesh.position.clone(),
|
|
@@ -2830,10 +2863,14 @@ var StyleHelper = class {
|
|
|
2830
2863
|
}
|
|
2831
2864
|
this.styleCollectors = [];
|
|
2832
2865
|
this.meshChangeHandlers.clear();
|
|
2833
|
-
const
|
|
2866
|
+
const evaluators = buildStyleConditionEvaluatorMap({
|
|
2834
2867
|
show: style.show,
|
|
2835
2868
|
conditions: style.conditions ?? []
|
|
2836
2869
|
});
|
|
2870
|
+
const { hiddenOidsList, groups } = buildAppearanceGroupsFromPropertyMap(propertyByOid, {
|
|
2871
|
+
show: style.show,
|
|
2872
|
+
conditions: style.conditions ?? []
|
|
2873
|
+
}, evaluators);
|
|
2837
2874
|
for (const { oids } of groups.values()) for (const oid of oids) this.styledOids.add(oid);
|
|
2838
2875
|
this.hiddenOids = new Set(hiddenOidsList);
|
|
2839
2876
|
const oidsToHide = [...hiddenOidsList];
|
|
@@ -2894,8 +2931,10 @@ function toMaterial(value) {
|
|
|
2894
2931
|
return getMaterialForHighlight(value);
|
|
2895
2932
|
}
|
|
2896
2933
|
function toStyleAppearance(ha) {
|
|
2934
|
+
const mat = ha.material;
|
|
2897
2935
|
return {
|
|
2898
|
-
material: toMaterial(
|
|
2936
|
+
material: typeof mat === "function" ? mat : mat instanceof Material ? mat : toMaterial(mat),
|
|
2937
|
+
mesh: ha.mesh,
|
|
2899
2938
|
translation: ha.translation,
|
|
2900
2939
|
scale: ha.scale,
|
|
2901
2940
|
rotation: ha.rotation,
|
|
@@ -2929,12 +2968,16 @@ var PartHighlightHelper = class {
|
|
|
2929
2968
|
mergeAppearanceByOid(propertyByOid) {
|
|
2930
2969
|
const appearanceByOid = /* @__PURE__ */ new Map();
|
|
2931
2970
|
for (const [, hl] of this.highlightGroups) {
|
|
2971
|
+
const evaluators = buildStyleConditionEvaluatorMap({
|
|
2972
|
+
show: hl.show,
|
|
2973
|
+
conditions: hl.conditions ?? []
|
|
2974
|
+
});
|
|
2932
2975
|
const conditions = (hl.conditions ?? []).map(([c, h]) => [c, toStyleAppearance(h)]);
|
|
2933
2976
|
for (const [oid, propertyData] of propertyByOid) {
|
|
2934
2977
|
if (propertyData == null) continue;
|
|
2935
2978
|
if (hl.oids && !hl.oids.includes(oid)) continue;
|
|
2936
|
-
if (hl.show && !evaluateStyleCondition(hl.show, propertyData)) continue;
|
|
2937
|
-
const app = resolveConditionsAppearance(conditions, propertyData);
|
|
2979
|
+
if (hl.show && !evaluateStyleCondition(hl.show, propertyData, evaluators)) continue;
|
|
2980
|
+
const app = resolveConditionsAppearance(conditions, propertyData, evaluators);
|
|
2938
2981
|
if (!app) continue;
|
|
2939
2982
|
appearanceByOid.set(oid, app);
|
|
2940
2983
|
}
|
|
@@ -2944,10 +2987,16 @@ var PartHighlightHelper = class {
|
|
|
2944
2987
|
/** 各组 show 失败需隐藏的 OID(与 setStyle 一致:show 不满足则隐藏原片) */
|
|
2945
2988
|
collectUnionShowHide(propertyByOid) {
|
|
2946
2989
|
const unionHide = /* @__PURE__ */ new Set();
|
|
2947
|
-
for (const [, hl] of this.highlightGroups)
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2990
|
+
for (const [, hl] of this.highlightGroups) {
|
|
2991
|
+
const evaluators = buildStyleConditionEvaluatorMap({
|
|
2992
|
+
show: hl.show,
|
|
2993
|
+
conditions: hl.conditions ?? []
|
|
2994
|
+
});
|
|
2995
|
+
for (const [oid, propertyData] of propertyByOid) {
|
|
2996
|
+
if (propertyData == null) continue;
|
|
2997
|
+
if (hl.oids && !hl.oids.includes(oid)) continue;
|
|
2998
|
+
if (hl.show && !evaluateStyleCondition(hl.show, propertyData, evaluators)) unionHide.add(oid);
|
|
2999
|
+
}
|
|
2951
3000
|
}
|
|
2952
3001
|
return unionHide;
|
|
2953
3002
|
}
|
|
@@ -3368,6 +3417,8 @@ var GLTFParserPlugin = class {
|
|
|
3368
3417
|
if (tileWithCache.engineData?.scene) this._onLoadModel(tileWithCache.engineData.scene);
|
|
3369
3418
|
return true;
|
|
3370
3419
|
}, null);
|
|
3420
|
+
this._notifyCollectors();
|
|
3421
|
+
if (this._options.style !== void 0) this._styleHelper?.setStyle(this._options.style ?? null);
|
|
3371
3422
|
}
|
|
3372
3423
|
_createPartEffectHost() {
|
|
3373
3424
|
return {
|
|
@@ -3488,8 +3539,9 @@ var GLTFParserPlugin = class {
|
|
|
3488
3539
|
if (!this.tiles) return null;
|
|
3489
3540
|
const cond = condition.trim();
|
|
3490
3541
|
if (!cond) return null;
|
|
3542
|
+
const evaluators = buildStyleConditionEvaluatorMap({ show: cond });
|
|
3491
3543
|
const targetOids = [];
|
|
3492
|
-
for (const oid of getAllOidsFromTiles(this.tiles)) if (evaluateStyleCondition(cond, getPropertyDataByOid(this.tiles, oid))) targetOids.push(oid);
|
|
3544
|
+
for (const oid of getAllOidsFromTiles(this.tiles)) if (evaluateStyleCondition(cond, getPropertyDataByOid(this.tiles, oid), evaluators)) targetOids.push(oid);
|
|
3493
3545
|
if (targetOids.length === 0) return null;
|
|
3494
3546
|
return this._getCenterFromOidList(targetOids);
|
|
3495
3547
|
}
|
|
@@ -3551,6 +3603,7 @@ var GLTFParserPlugin = class {
|
|
|
3551
3603
|
*/
|
|
3552
3604
|
_onLoadModelCB = ({ scene }) => {
|
|
3553
3605
|
this._onLoadModel(scene);
|
|
3606
|
+
this._notifyCollectors();
|
|
3554
3607
|
};
|
|
3555
3608
|
/**
|
|
3556
3609
|
* Tiles load end callback
|
|
@@ -3569,6 +3622,7 @@ var GLTFParserPlugin = class {
|
|
|
3569
3622
|
_notifyCollectors() {
|
|
3570
3623
|
for (const collector of this.collectors) collector._updateMeshes();
|
|
3571
3624
|
this._styleHelper?.onTilesLoadEnd();
|
|
3625
|
+
this._partHighlightHelper?.onTilesLoadEnd();
|
|
3572
3626
|
}
|
|
3573
3627
|
_registerCollector(collector) {
|
|
3574
3628
|
this.collectors.add(collector);
|
|
@@ -3721,8 +3775,9 @@ var GLTFParserPlugin = class {
|
|
|
3721
3775
|
targetOids = [...new Set(params.oids)].sort((a, b) => a - b);
|
|
3722
3776
|
} else {
|
|
3723
3777
|
const candidate = params.oids.length === 0 ? getAllOidsFromTiles(this.tiles) : [...new Set(params.oids)];
|
|
3778
|
+
const evaluators = buildStyleConditionEvaluatorMap({ show: cond });
|
|
3724
3779
|
targetOids = [];
|
|
3725
|
-
for (const oid of candidate) if (evaluateStyleCondition(cond, getPropertyDataByOid(this.tiles, oid))) targetOids.push(oid);
|
|
3780
|
+
for (const oid of candidate) if (evaluateStyleCondition(cond, getPropertyDataByOid(this.tiles, oid), evaluators)) targetOids.push(oid);
|
|
3726
3781
|
targetOids.sort((a, b) => a - b);
|
|
3727
3782
|
}
|
|
3728
3783
|
return this._getMeshesByOidsInternal(targetOids);
|
|
@@ -3944,6 +3999,6 @@ var GLTFParserPlugin = class {
|
|
|
3944
3999
|
}
|
|
3945
4000
|
};
|
|
3946
4001
|
//#endregion
|
|
3947
|
-
export { GLTFParserPlugin, MeshCollector,
|
|
4002
|
+
export { GLTFParserPlugin, MeshCollector, buildStyleConditionEvaluatorMap, compileStyleCondition, decodeGzipBase64DataUriSync, evaluateStyleCondition, extractStyleMaterialMaps, getStructureDataUriFromTileset, meshCollectorGroupKey, meshCollectorQueryCacheKey, normalizeMeshCollectorOids, parseEmbeddedStructureDataFromTilesSync };
|
|
3948
4003
|
|
|
3949
4004
|
//# sourceMappingURL=gltf-parser-plugin.module.js.map
|