Я помещаю новый материал через
highlight(dbId, color) {
let viewer = this.viewer;
let myMaterial = this.createMaterial(color);
// used to rescale and remove the z-fighting
let scaleRatio = 1.005; // this was determined as optimal through visual inspection
var tree = NOP_VIEWER.model.getData().instanceTree;
var result = new Object();
result.dbId = dbId;
result.oldMaterials = {};
tree.enumNodeFragments(dbId,
function(fragId) {
result.oldMaterials[fragId] = viewer.model.getFragmentList().getMaterial(fragId);
viewer.model.getFragmentList().setMaterial(fragId, myMaterial);
/* important technique if you want to remove z-fighting */
let fragProxy = viewer.impl.getFragmentProxy(viewer.model, fragId);
fragProxy.scale = new THREE.Vector3(scaleRatio, scaleRatio, scaleRatio);
fragProxy.updateAnimTransform();
},
true);
viewer.impl.invalidate(true);
return result;
}
createMaterial(color) {
const material = new THREE.MeshPhongMaterial({
side: THREE.DoubleSide,
reflectivity: 0.0,
flatShading: true,
transparent: true,
opacity: 0.5,
color
});
const materials = this.viewer.impl.matman();
materials.addMaterial(
"MyCustomMaterial" + color.toString(),
material,
true);
return material;
}
Затем я пытаюсь вернуть его к предыдущему материалу через
unHighlight(dbId, oldMaterials) {
let viewer = this.viewer;
var tree = NOP_VIEWER.model.getData().instanceTree;
let scaleRatio = 1.020; // this was determined as optimal through visual inspection
tree.enumNodeFragments(dbId,
function (fragId) {
const materials = this.viewer.impl.matman();
materials.addMaterial(
"MyCustomMaterial" + dbId + fragId,
oldMaterials[fragId],
true);
viewer.model.getFragmentList().setMaterial(fragId, oldMaterials[fragId]);
/* important technique if you want to remove z-fighting */
let fragProxy = viewer.impl.getFragmentProxy(viewer.model, fragId);
fragProxy.scale = new THREE.Vector3(scaleRatio, scaleRatio, scaleRatio);
fragProxy.updateAnimTransform();
},
true);
viewer.impl.invalidate(true);
}
Но это не дало видимых результатов.Как я могу вернуться к предыдущим материалам?Если я правильно понимаю логику средства просмотра, у него есть материал для каждого фрагмента каждого dbId.И при вызове setMaterial () мы заменяем предыдущий материал нашим.И чтобы вернуть его, мы должны сохранить старый материал через getMaterial () для каждого элемента fragId, а затем вернуть его через setMaterial ().Но по какой-то причине этот подход не работает.
UPD:
Я обнаружил странную вещь.Когда я сохраняю данные об этом в консоли перед сохранением материала, оказывается, что для одного фрагмента указано несколько материалов.
highlight(externalId, color, dict) {
let viewer = this.viewer;
var dbId = dict[externalId];
let myMaterial = this.createMaterial(color);
// used to rescale and remove the z-fighting
let scaleRatio = 1.005; // this was determined as optimal through visual inspection
var tree = NOP_VIEWER.model.getData().instanceTree;
var result = new Object();
result.dbId = dbId;
result.oldMaterials = {};
tree.enumNodeFragments(dbId,
function (fragId) {
const previousMaterial = viewer.model.getFragmentList().getMaterial(fragId).clone();
//!!!!!!!!!!!!!!!!!!!!
console.log(dbId);
console.log(fragId);
console.log(previousMaterial);
//!!!!!!!!!!!!!!!!!!!!
result.oldMaterials[fragId] = previousMaterial;
viewer.model.getFragmentList().setMaterial(fragId, myMaterial);
/* important technique if you want to remove z-fighting */
let fragProxy = viewer.impl.getFragmentProxy(viewer.model, fragId);
fragProxy.scale = new THREE.Vector3(scaleRatio, scaleRatio, scaleRatio);
fragProxy.updateAnimTransform();
},
true);
viewer.impl.invalidate(true);
return result;
}