突出显示选定项
1. 要向运行时用户提供清晰的视觉反馈,用户在模型中选择子装配或部件项时,应触发可视指示符。这有助于用户确认他们正在查看正确模型项的数据。为此,我们会将突出显示着色器应用到选定的模型项。将以下内容添加到 Visualization.js:
// call this function to highlight the list of selected parts
//
var highlightParts = (selectedList, modelId) => {
var highlightedList = [];
// run over all the items in the list and assign the highlight shader
selectedList.forEach( (partId) => {
var renderingPartId = modelId + "-" + partId;
var shader = "highlight;r f 1;g f 0.5;b f 0.25;a f 1" + (twx.app.isPreview() ? ";virtualMode f 1.0":"");
tml3dRenderer.setProperties(renderingPartId, { shader: shader, opacity: 1.0, hidden: false });
// and keep a record of what we highlighted - so that we wan undo it later
//
highlightedList.push(renderingPartId);
});
return highlightedList;
}
2. 此外,当用户在先前选定的子装配之外单击鼠标,或选择不同的子装配时,突出显示着色器必须相应更新。这可以确保只有当前选定的模型项在视觉上得到强调,从而在整个交互过程中保持清晰。因此,还需要将以下内容添加到 Visualization.js:
// call this function to clear the highlights
//
var highlightReset = (highlightedList) => {
// run over all the items in the list and unsasign the shader
//
highlightedList.forEach( (modelIdpartId) => {
tml3dRenderer.setProperties(modelIdpartId,{ shader:"", opacity: 0.2, hidden: !twx.app.isPreview() });
});
return [];
}
3. 现在,当用户从部件列表中选择某一项时,该项应突出显示。请注意以下代码片段中使用的逻辑,这在您使用自己的模型时尤为重要。该逻辑依赖于必须在 Creo Illustrate 中定义且可用的属性,并在运行时为每个部件加载这些属性。如果使用不同的键或自定义属性来显示特定于部件的数据,请确保相应地更新以下代码中的属性参考,以匹配 Visualization.js 中的模型结构:
// used to track which items are highlighted
$scope.lit = [];
// called when the user taps on a property in the named list, or taps on a part in the view - this changes the 'current' field
//
$scope.$watch(
() => {
return ($scope.view.wdg.partsList.list != undefined &&
$scope.view.wdg.partsList.list.current != undefined) ? JSON.stringify($scope.view.wdg.partsList.list.current) : "";
},
//value == 'currentSelectedPart',
(value) => {
highlightReset($scope.lit);
var partNumber = JSON.parse(value);
// first of all, lets get all the metadata values for this selected item
//
var plist = [];
PTC.Metadata.fromId(partNumber.model)
.then ( (metadata) => {
// find all the items with this partnumber
//
plist = metadata.find(metadataKey).like(partNumber.name);
if (plist == undefined)
{
return;
}
// highlight those items
//
$scope.lit = highlightParts(plist.getSelected(), partNumber.model);
// now find some interesting properties
//
var interestingProperties = ["cost","supplier","weight","partNumber"];
// this function (declared inline) is used to get the property values (see above) for eeach of the items
// in the previously acquired partnmubered plist - it will iterate through each item (idpath) and get the
// properties for each item; if found, they are captured into an array of name=value pairs.
//
var getInteresting = (ip) => {
var ilist = ip;
return function(idpath) {
const res = this.get(idpath, ilist);
var retobj = { path:idpath };
if (res != undefined && res.length === ilist.length) for (var p=0;p<ilist.length;p++) {
// add each result as a new property in the return body
retobj[ilist[p]] = res[p];
}
return retobj;
}
}
// get a list of items with this property set
//
plist = plist.getSelected(getInteresting(interestingProperties));
// helper function to get and format the properties - this generates a list of name|value pairs
//
var getNameValues = (items) => {
var nv = [];
items.forEach( (i) => {
Object.keys(i).forEach( (j) =>{
if (interestingProperties.includes(j)) nv.push({name:j, value:i[j]});
})
})
return nv;
}
// we need to turn this into a list of item/name/value
//
$scope.view.wdg.propertiesList.data = getNameValues(plist);
//
// and show the popup
//
twx.app.fn.triggerWidgetService("propertyPopup", 'showpopup')
})
}
);
4. 如果用户没有特定的部件名称或 ID,可以直接在模型上交互选择相关子装配。对于此场景,请添加以下内容:
// called if the user taps on a part
$scope.$on("userpick", (event, model, type, args) => {
PTC.Metadata.fromId(model)
.then ( (metadata) => {
var pathId = JSON.parse(args).occurrence;
var sid = metadata.get(pathId, metadataKey);
var findMetaDataKey = (p) => {
// simple inline closure that will test if the item name is the value specificed (p in this case)
// this gets called for all items in the list (see findIndex, below)
//
return function(v) { return v.name == p; }
}
// work out which row we need to select
//
var fid = $scope.view.wdg.partsList.list.findIndex(findMetaDataKey(sid));
// return call here if not found
// ... and mark it as selected
//
$scope.view.wdg.partsList.list.forEach( (v,i) => { v._isSelected = (i == fid) });
// and get the row to highlight in 3d
//
$scope.view.wdg.partsList.list.current = $scope.view.wdg.partsList.list.filter( (v,i) => { return i == fid })[0];
})
});