// module: TRUE
// @ts-ignore
import { gui } from "./post_entities_of_interest_gui.jsi";
/**
* @typedef {Object} EntityOfInterest
* @property {string} name
* @property {string[]} parts
* @property {String} type
* @property {String[]} partsOfEntity
*/
/**
* The data object in the workflow file
* @typedef {Object} data
* @property {EntityOfInterest[]} entities_of_interest
*/
/** @type {data} */
let data; // where the workflows data is stored from the .JSON
let model_id; // the current model in use being passed around the program
let window_id; // the current window in use being passed around the program
let entryModelList; // the list of models in use when a button is pressed
let dir; // the file directory for saving GLB Exports
let GLBOutput; // the GLB output option - Current Frame or Animation
let GLBFrameRate; // the GLB Frame Rate option if Animation is selected for GLBOutput
set_up();
/* Show the first window "Window1" */
if (gui) gui.Window1.Show(false);
/**
* Sets up the window with callback functions from the GUI, fills the WidgetItems for the listbox based on JSON data, checks there are just 1 model per window and sets current model
*/
function set_up() {
for (let m = 0; m < Workflow.NumberOfSelectedModels(); m++) {
model_id = Workflow.ModelIdFromIndex(m);
/** @type {data} */
// @ts-ignore
data = Workflow.ModelUserDataFromIndex(m);
if (SetCurrentModel(model_id)) {
// TRUE if model is present (false if model is deleted etc)
// Adds each entry from the JSON including the model number
for (let i = 0; i < data.entities_of_interest.length; i++) {
let newEntry =
"M" +
model_id +
" | " +
data.entities_of_interest[i].name +
" | " +
data.entities_of_interest[i].type +
" | " +
data.entities_of_interest[i].parts;
let newItem = new WidgetItem(gui.Window1.lbEntity, newEntry);
newItem.hover = data.entities_of_interest[i].parts.toString();
}
}
}
SetCurrentModel(model_id);
/* Blank all the parts in the model first. Need to get
* the window the model is in to do this. */
let n = GetNumberOf(WINDOW);
window_id = -1;
let nm = [1, 1];
for (let m = 1; m <= n; m++) {
let wm = GetWindowModels(m);
for (var j = 0; j < wm.nm; j++) {
if (wm.list[j] == model_id) {
window_id = m;
nm[0] = wm.nm;
nm[1] = j + 1;
break;
}
}
}
// Checks if each window just contains 1 model
if (nm[0] > 1) {
let answer = Window.Error(
"Error",
"This tool does not work correctly with multiple models in one window. \nExit the script?",
Window.YES | Window.NO
);
if (answer == Window.YES) {
Exit();
}
}
if (window_id == -1) {
WarningMessage("Unable to find model window");
return;
}
// callbacks
gui.Window1.lbEntity.onClick = update_buttons;
gui.Window1.btnReset.onClick = reset_button;
gui.Window1.btnOnly.onClick = only;
gui.Window1.btnHighlight.onClick = highlight;
gui.Window1.btnGLB.onClick = GLB_edit;
gui.Window1.helpBtn.onClick = workflow_manual;
gui.WindowGLB.btnFile.onClick = GLB_dir;
gui.WindowGLB.cbOutput.onChange = GLB_output_change;
gui.WindowGLB.btnExport.onClick = GLB;
gui.WindowGLB.btnCancel.onClick = GLB_cancel;
gui.WindowGLB.txtDir.onChange = update_export_button;
// Directory icon added to file button
gui.WindowGLB.btnFile.DirectoryIcon(Widget.BLACK, Widget.GREY);
// These become active if GLB Output 'Animation' is selected
gui.WindowGLB.lblFrameRate.active = false;
gui.WindowGLB.txtFrameRate.active = false;
}
/**
* Enables and Disables the buttons on the window according to how many widgetItems are selected
*/
function update_buttons() {
let widgetItems = gui.Window1.lbEntity.WidgetItems();
let widgetItemsSelected = 0;
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
widgetItemsSelected++;
}
}
if (widgetItemsSelected == 0) {
gui.Window1.btnOnly.active = false;
gui.Window1.btnHighlight.active = false;
gui.Window1.btnGLB.active = false;
} else {
gui.Window1.btnOnly.active = true;
gui.Window1.btnHighlight.active = true;
gui.Window1.btnGLB.active = true;
}
}
/**
* Resets the model back to default ready for the new action (button press) to commence and checks that an entry is selected
* @returns {Boolean} true if entities are selected, false if not
*/
function reset(option) {
// Sets window based on the model being looped through
DialogueInput("/CW " + window_id, "UNBLANK ALL");
if (option == "full") {
DialogueInput("/PROPERTIES TRANSPARENCY ALL", "0");
DialogueInput("/PROPERTIES COLOUR ORIGINAL");
}
// checks if entry is selected and returns result
let widgetItems = gui.Window1.lbEntity.WidgetItems();
let widgetsSelected = 0;
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
widgetsSelected++;
}
}
if (widgetsSelected == 0) {
return false;
}
return true;
}
/**
* Resets the model back to default, a button that can be pressed by the user
*/
function reset_button() {
for (let m = 0; m < Workflow.NumberOfSelectedModels(); m++) {
model_id = Workflow.ModelIdFromIndex(m);
// Finds the window number for the model in the loop
find_window_number_for_model();
DialogueInput("/CW " + window_id, "UNBLANK ALL");
DialogueInput("/PROPERTIES TRANSPARENCY ALL", "0");
DialogueInput("/PROPERTIES COLOUR ORIGINAL");
DialogueInput("/AC");
}
}
/**
* Completes the action as selected by the button pressing by the user
* @param {string} method the action being completed by the user. Valid options are Only, Highlight or GLB
*/
function action(method) {
let modelID;
// Loops through the workflows selected and gets the data for the model
for (let m = 0; m < Workflow.NumberOfSelectedModels(); m++) {
modelID = Workflow.ModelIdFromIndex(m);
/** @type {data} */
// @ts-ignore
data = Workflow.ModelUserDataFromIndex(m);
// Checks if the workflows modelID matches the model_id of the D3PLOT screen
if (modelID.toString() == model_id.toString()) {
// if TRUE then loops through the WidgetItems (entries) and makes sure they are selected
let widgetItems = gui.Window1.lbEntity.WidgetItems();
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
// if TRUE then WidgetItem is selected
// Splits up the WidgetItem text to determine the model that the entry is connected to
let text = widgetItems[i].text;
text = text.split(" |");
text = text[0].split("M");
text = text[1];
// Checks if the model matches the model in the entry that has been selected
if (modelID.toString() == text.toString()) {
// if TRUE sets it to the model that we have confirmed is the model that is specified in the entry
SetCurrentModel(modelID);
// Loops through the data for the selected model
for (let j = 0; j < data.entities_of_interest.length; j++) {
// Gets the name of the widgetItem that has been selected that we are looping through
let name = widgetItems[i].text;
name = name.split(" |");
name = name[1].trim(); /* Name */
// if the name in the data for the selected model we are looping through matches the name of the WidgetItem entry we are looping through
if (data.entities_of_interest[j].name == name) {
// if TRUE we have now got the correct data entry to match with the correct widgetItem entry for the model
// Determines if the entry type is a part or a part set and gets the list of parts for the entry
let parts;
if (data.entities_of_interest[j].type.toString() == "Parts") {
parts = data.entities_of_interest[j].parts;
}
if (data.entities_of_interest[j].type.toString() == "Part Set") {
parts = data.entities_of_interest[j].partsOfEntity;
}
let neg_pid = parts.map((x) => -x);
// Completes the action
if (method == "Only") {
Unblank(PART, neg_pid, window_id);
}
if (method == "Highlight") {
Blank(PART, "ALL", window_id);
Unblank(PART, neg_pid, window_id);
DialogueInput("/REDRAW");
DialogueInput("/PROPERTIES COLOUR PARTS AV", "RED");
DialogueInput("/PROPERTIES TRANSPARENCY PARTS AV", "0");
Unblank(PART, "ALL", window_id);
}
if (method == "GLB") {
Blank(PART, "ALL", window_id);
Unblank(PART, neg_pid, window_id);
DialogueInput("/AC");
if (GLBOutput == "Current Frame") {
DialogueInput(
"/IMAGES ONLY_WINDOW",
window_id,
"EXPORT_3D",
"CURRENT_FRAME",
dir + "/" + data.entities_of_interest[j].name
);
}
if (GLBOutput == "Animation") {
DialogueInput("/IMAGES FRAME_RATE", GLBFrameRate);
DialogueInput(
"/IMAGES ONLY_WINDOW",
window_id,
"EXPORT_3D",
"ANIMATION",
dir + "/" + data.entities_of_interest[j].name
);
}
}
}
}
}
}
}
DialogueInput("/AC");
}
}
}
/**
* When looping through the models that have been selected after selecting entries, then fiund the window number for the stated model_id
*/
function find_window_number_for_model() {
SetCurrentModel(model_id);
let n = GetNumberOf(WINDOW);
window_id = -1;
for (let m = 1; m <= n; m++) {
let wm = GetWindowModels(m);
for (var j = 0; j < wm.nm; j++) {
if (wm.list[j] == model_id) {
window_id = m;
break;
}
}
}
}
/**
* @returns {Array} entryModelList
* Finds out the models that have been selected by the user after a button press by searching through the selected WidgetItems and putting them into an array
*/
function find_entry_model_list() {
let widgetItems = gui.Window1.lbEntity.WidgetItems();
for (let i = 0; i < widgetItems.length; i++) {
if (widgetItems[i].selected) {
// Split up the WidgetItem text and find the model number
let text = widgetItems[i].text;
text = text.split(" |");
text = text[0].split("M");
text = text[1]; // model number of selected entry
// Checks if the array already contains the model, if it does not then adds the model to the list
if (!entryModelList.includes(text)) {
entryModelList.push(text);
}
}
}
return entryModelList;
}
/**
* Only the selected entities
*/
function only() {
// Creates the entry model list to find out which models have been selected for use
entryModelList = [];
entryModelList = find_entry_model_list();
// Loops through the models selected
for (let x = 0; x < entryModelList.length; x++) {
// Sets model_id to the model in the loop
model_id = Number(entryModelList[x]);
// Finds the window number for the model in the loop
find_window_number_for_model();
// Resest the window of the model in the loop, if no entries are selcted then returns
if (!reset("full")) return;
// Blanks all parts ready for action
DialogueInput("/BLANK ALL");
// Completes the blanking
action("Only");
}
}
/**
* Highlight the selected entities
*/
function highlight() {
// Creates the entry model list to find out which models have been selected for use
entryModelList = [];
entryModelList = find_entry_model_list();
// Loops through the models selected
for (let x = 0; x < entryModelList.length; x++) {
// Sets model_id to the model in the loop
model_id = Number(entryModelList[x]);
// Finds the window number for the model in the loop
find_window_number_for_model();
// Resest the window of the model in the loop, if no entries are selcted then returns
if (!reset("full")) return;
// Sets all parts we don't want highlighting to 90% transparency and grey ready for action
DialogueInput("/PROPERTIES TRANSPARENCY ALL", "90");
DialogueInput("/PROPERTIES COLOUR ALL GREY");
// Completes the highlighting
action("Highlight");
}
}
/**
* Opens window to set GLB Export options
*/
function GLB_edit() {
gui.WindowGLB.Show(false);
}
/**
* GLB Export the selected entities when export button is pressed in GLB edit window
*/
function GLB() {
GLBOutput = gui.WindowGLB.cbOutput.text;
GLBFrameRate = gui.WindowGLB.txtFrameRate.text;
dir = gui.WindowGLB.txtDir.text;
if (dir == null || !File.IsDirectory(dir)) {
Window.Message("", "Invalid file directory, cancelling GLB Export");
return;
}
gui.WindowGLB.Hide();
// Creates the entry model list to find out which models have been selected for use
entryModelList = [];
entryModelList = find_entry_model_list();
// Loops through the models selected
for (let x = 0; x < entryModelList.length; x++) {
// Sets model_id to the model in the loop
model_id = Number(entryModelList[x]);
// Finds the window number for the model in the loop
find_window_number_for_model();
// Resest the window of the model in the loop, if no entries are selcted then returns
if (!reset()) return;
// Complets the GLB Export
action("GLB");
Unblank(PART, "ALL", window_id);
DialogueInput("/AC");
}
}
/**
* When the GLB output is changed between Current Frame and Animation, enable Frame Rate option for Animation
*/
function GLB_output_change() {
if (gui.WindowGLB.cbOutput.text == "Current Frame") {
gui.WindowGLB.lblFrameRate.active = false;
gui.WindowGLB.txtFrameRate.active = false;
} else {
gui.WindowGLB.lblFrameRate.active = true;
gui.WindowGLB.txtFrameRate.active = true;
}
}
/**
* Enables and disables the GLB export button depending on a correct directory or not
*/
function update_export_button() {
dir = gui.WindowGLB.txtDir.text;
if (File.IsDirectory(dir)) {
gui.WindowGLB.btnExport.active = true;
} else {
gui.WindowGLB.btnExport.active = false;
}
}
/**
* When the file selector button is pressed in GLB edit window, to select the location to save the GLB Exports to
*/
function GLB_dir() {
let cancelText = gui.WindowGLB.txtDir.text;
dir = Window.GetDirectory();
if (dir == null) {
WarningMessage("No directory selected");
gui.WindowGLB.txtDir.text = cancelText;
} else {
gui.WindowGLB.txtDir.text = dir;
}
update_export_button();
}
/**
* Closes GLB Export options window when cancel is pressed
*/
function GLB_cancel() {
gui.WindowGLB.Hide();
}
/**
* Opens up the clickhelp manual when the help button is pressed
*/
function workflow_manual() {
OpenManual("d3plot", "entities-of-interest.html");
}