Skip to content

Handling Model Navigation

The lifecycle of your extension will vary based on user actions and your extension setup in the manifest.

Window TypeModel Can Change
headless✅
floating✅
modal❌
sidebar✅
tab✅

Note that it’s possible for getActiveModel to throw an error in the case where there is no active model, for example if a user on Desktop closes all of their models.

Note that these patterns are only a guide and can be used in conjunction with best practices if you are using a framework (Vue, React, Angular, etc.).

Applicable when your extension comprises actions that can be performed on the model with no need to display update to date information to the user.

async function someAction() {
// Always fetch the active model and perform the action
// Pass this model through any nested functions to ensure data consistency.
const model = await SketchUpApi.getActiveModel();
model.performOperation((op) => {
// For convenience and consistency you can extract the model reference from the operation.
op.createFace(op.model, [[0, 0, 0], [100, 0, 0], [100, 100, 0], [0, 100, 0]]);
}, 'Created a face');
}

Applicable for reporting style extensions where the reporting calculation is fairly expensive. The general idea is that you display an “update” button when the model changes.

// Could default to false if you process the model on extension startup.
let needsUpdate = true;
// You may only want to update this when you've processed this to capture the model revision when the display was changed.
let model = await SketchUpApi.getActiveModel();
SketchUpApi.observeActiveModel(async (modelMeta) => {
model = await modelMeta.getModel();
if (modelMeta.isDifferentModel(model)) {
// Perhaps you have special handling for an entirely new model
}
if (modelMeta.isModelChanged(model)) {
// This branch will execute if the model is different OR the model revision has changed
console.log(`Model revision ${modelMeta.revision}`)
// You may do more complex logic here to determine this state
needsUpdate = true;
}
});
async function processModel() {
// Your extension application logic that extracts information from the model
needsUpdate = false;
}

Alternatively you can use some sort of debouncing logic to delay the expensive work while rapid changes are being made to the model.

Applicable for extensions that always need to display up-to-date information, or perform some sort of post-processing work.

let model = await SketchUpApi.getActiveModel();
SketchUpApi.observeActiveModel(async (modelMeta) => {
// You may not want to debounce this to account for rapid fire changes
model = await modelMeta.getModel();
await processModel();
});
async function processModel() {
// Your extension application logic that extracts information from the model
}