The viewer JS/HTML/bundles are now committed in javascript/ (declared via pyproject [tool.comfy] web = "javascript") instead of being copied from the shared comfy-3d-viewers pip package at prestartup. Consequences: - requirements.txt is now just comfy-env (host env installs nothing else, per the never-touch-the-host-env principle) - prestartup_script.py no longer copies viewers or web_src; it keeps only setup_env() and the input-asset copies - WEB_DIRECTORY attribute removed; the pyproject declaration is the single source (served at /extensions/comfyui-geometrypack/, keyed by project name) - web_src/ deleted; its 6 widgets now live in javascript/js/ as the tracked source, edited directly - viewer_pbr.html hardcoded-fallback URL updated to the new mount name Iframe URLs auto-detect the mount from import.meta.url, so the folder rename and mount-name change are transparent at runtime.
214 lines
6.4 KiB
JavaScript
214 lines
6.4 KiB
JavaScript
/**
|
|
* TextureManager - Texture handling for GLTF/GLB meshes
|
|
*
|
|
* Manages texture extraction, material fixes, and rendering configuration
|
|
* for properly displaying textured meshes in VTK.js.
|
|
*/
|
|
|
|
/**
|
|
* Texture information structure
|
|
* @typedef {Object} TextureInfo
|
|
* @property {boolean} hasTexture - Whether a texture was found
|
|
* @property {boolean} hasMaterial - Whether PBR material properties exist
|
|
* @property {string} textureType - Type of texture found (baseColor, diffuse, etc.)
|
|
*/
|
|
|
|
export class TextureManager {
|
|
/**
|
|
* Create a TextureManager
|
|
* @param {Object} vtk - VTK.js global object
|
|
* @param {Object} renderWindow - VTK render window
|
|
*/
|
|
constructor(vtk, renderWindow) {
|
|
this.vtk = vtk;
|
|
this.renderWindow = renderWindow;
|
|
}
|
|
|
|
/**
|
|
* Apply texture fixes to an actor
|
|
* This fixes common issues with GLTF texture rendering in VTK.js
|
|
* @param {Object} actor - VTK actor
|
|
* @returns {TextureInfo} Texture information
|
|
*/
|
|
applyTextureFixes(actor) {
|
|
const property = actor.getProperty();
|
|
const mapper = actor.getMapper();
|
|
const info = {
|
|
hasTexture: false,
|
|
hasMaterial: false,
|
|
textureType: null
|
|
};
|
|
|
|
if (!property) {
|
|
return info;
|
|
}
|
|
|
|
// CRITICAL FIX: Remove metallicRoughnessTexture if present
|
|
// VTK.js GLTFImporter may use this instead of baseColorTexture
|
|
if (typeof property.setRMTexture === 'function') {
|
|
property.setRMTexture(null);
|
|
}
|
|
if (typeof property.setMetallicRoughnessTexture === 'function') {
|
|
property.setMetallicRoughnessTexture(null);
|
|
}
|
|
|
|
// Try multiple methods to get the base color texture
|
|
let texture = null;
|
|
|
|
if (typeof property.getBaseColorTexture === 'function') {
|
|
texture = property.getBaseColorTexture();
|
|
if (texture) info.textureType = 'baseColor';
|
|
}
|
|
if (!texture && typeof property.getDiffuseTexture === 'function') {
|
|
texture = property.getDiffuseTexture();
|
|
if (texture) info.textureType = 'diffuse';
|
|
}
|
|
if (!texture && typeof property.getTexture === 'function') {
|
|
texture = property.getTexture();
|
|
if (texture) info.textureType = 'generic';
|
|
}
|
|
|
|
if (texture) {
|
|
info.hasTexture = true;
|
|
actor.addTexture(texture);
|
|
}
|
|
|
|
// Check for PBR material properties
|
|
if (typeof property.getMetallic === 'function' ||
|
|
typeof property.getRoughness === 'function') {
|
|
info.hasMaterial = true;
|
|
}
|
|
|
|
// Set material to non-metallic for proper texture display
|
|
if (typeof property.setMetallic === 'function') {
|
|
property.setMetallic(0.0);
|
|
}
|
|
if (typeof property.setRoughness === 'function') {
|
|
property.setRoughness(1.0);
|
|
}
|
|
if (typeof property.setInterpolation === 'function') {
|
|
property.setInterpolation(2); // Phong shading
|
|
}
|
|
|
|
// Configure mapper for texture rendering
|
|
if (mapper) {
|
|
mapper.setScalarVisibility(false);
|
|
mapper.modified();
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
/**
|
|
* Apply texture fixes to multiple actors
|
|
* @param {Object[]} actors - Array of VTK actors
|
|
* @returns {TextureInfo} Combined texture information
|
|
*/
|
|
applyTextureFixesMultiple(actors) {
|
|
const combinedInfo = {
|
|
hasTexture: false,
|
|
hasMaterial: false,
|
|
texturedActors: 0
|
|
};
|
|
|
|
actors.forEach(actor => {
|
|
const info = this.applyTextureFixes(actor);
|
|
if (info.hasTexture) {
|
|
combinedInfo.hasTexture = true;
|
|
combinedInfo.texturedActors++;
|
|
}
|
|
if (info.hasMaterial) {
|
|
combinedInfo.hasMaterial = true;
|
|
}
|
|
});
|
|
|
|
return combinedInfo;
|
|
}
|
|
|
|
/**
|
|
* Configure renderer for texture display
|
|
* @param {Object} renderer - VTK renderer
|
|
*/
|
|
configureRenderer(renderer) {
|
|
// Enable two-sided lighting for better texture visibility
|
|
if (typeof renderer.setTwoSidedLighting === 'function') {
|
|
renderer.setTwoSidedLighting(true);
|
|
}
|
|
|
|
// Disable shadows (can interfere with texture display)
|
|
if (typeof renderer.setUseShadows === 'function') {
|
|
renderer.setUseShadows(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set actor appearance for non-textured display (solid color)
|
|
* @param {Object} actor - VTK actor
|
|
* @param {number[]} color - RGB color array [0-1 range]
|
|
*/
|
|
setActorColor(actor, color = [1.0, 1.0, 1.0]) {
|
|
const property = actor.getProperty();
|
|
const mapper = actor.getMapper();
|
|
|
|
if (property) {
|
|
property.setColor(...color);
|
|
}
|
|
|
|
if (mapper) {
|
|
mapper.setScalarVisibility(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Extract texture information from actor without modifying it
|
|
* @param {Object} actor - VTK actor
|
|
* @returns {TextureInfo} Texture information
|
|
*/
|
|
getTextureInfo(actor) {
|
|
const property = actor.getProperty();
|
|
const info = {
|
|
hasTexture: false,
|
|
hasMaterial: false,
|
|
textureType: null
|
|
};
|
|
|
|
if (!property) {
|
|
return info;
|
|
}
|
|
|
|
// Check for textures
|
|
if (typeof property.getBaseColorTexture === 'function' && property.getBaseColorTexture()) {
|
|
info.hasTexture = true;
|
|
info.textureType = 'baseColor';
|
|
} else if (typeof property.getDiffuseTexture === 'function' && property.getDiffuseTexture()) {
|
|
info.hasTexture = true;
|
|
info.textureType = 'diffuse';
|
|
} else if (typeof property.getTexture === 'function' && property.getTexture()) {
|
|
info.hasTexture = true;
|
|
info.textureType = 'generic';
|
|
}
|
|
|
|
// Check for material
|
|
if (typeof property.getMetallic === 'function' ||
|
|
typeof property.getRoughness === 'function') {
|
|
info.hasMaterial = true;
|
|
}
|
|
|
|
return info;
|
|
}
|
|
|
|
/**
|
|
* Check if GLTF texture support is available
|
|
* @returns {boolean}
|
|
*/
|
|
isTextureSupported() {
|
|
try {
|
|
return this.vtk.IO.Geometry.vtkGLTFImporter !== undefined;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
export default TextureManager;
|