Simplio3D

Conditional Logic

Define rules that dynamically show/hide option blocks or specific variants based on user selections. Rules evaluate at runtime using "all" (AND) or "any" (OR) logic operators.

How Conditional Logic Works

Hide rules: Block/variants start visible and become hidden when conditions match.

Show rules: Block/variants start hidden and become visible when conditions match.

Evaluation order: Hide rules first, then show rules can override.

Match types: is-selected and is-not-selected

Auto-apply on show: When a block transitions from hidden → visible (e.g. via a show / block rule), the default or previously-selected material from that block is automatically applied to the 3D viewport. This ensures the model always reflects the newly-visible block's material without requiring an explicit user click.

Add Conditional Rules to a Block

PUT/projects/:id/option-blocks/:blockId
// Hide the "Armrest Color" block when "Armrests" toggle is set to "without"
const response = await fetch(BASE_URL + '/projects/proj_123/option-blocks/blk_armrest_color', {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    conditionalRules: [
      {
        id: crypto.randomUUID(),
        action: 'hide',
        targetScope: 'block',
        targetVariantIds: [],
        operator: 'all',
        conditions: [
          {
            id: crypto.randomUUID(),
            sourceBlockId: 'blk_armrests',
            matchType: 'is-selected',
            sourceVariantIds: ['var_without_armrests']
          }
        ]
      }
    ]
  })
});

Variant-Level Conditional Logic

// Hide specific fabric options when "Outdoor" is selected in another block
const rules = [{
  id: crypto.randomUUID(),
  action: 'hide',
  targetScope: 'variants',
  targetVariantIds: ['var_silk', 'var_velvet'], // These fabrics are indoor-only
  operator: 'all',
  conditions: [{
    id: crypto.randomUUID(),
    sourceBlockId: 'blk_environment',
    matchType: 'is-selected',
    sourceVariantIds: ['var_outdoor']
  }]
}];

// Show premium materials only when "Enterprise" plan is detected
const showPremiumRule = {
  id: crypto.randomUUID(),
  action: 'show',
  targetScope: 'variants',
  targetVariantIds: ['var_carbon_fiber', 'var_titanium'],
  operator: 'any',
  conditions: [{
    id: crypto.randomUUID(),
    sourceBlockId: 'blk_tier',
    matchType: 'is-selected',
    sourceVariantIds: ['var_enterprise', 'var_premium']
  }]
};

Multi-Condition Rules (AND / OR)

// Show the "Heated Seats" option ONLY when BOTH conditions are met:
// 1. Vehicle type is "SUV" or "Sedan"
// 2. Climate package is selected
const rule = {
  id: crypto.randomUUID(),
  action: 'show',
  targetScope: 'block',
  targetVariantIds: [],
  operator: 'all', // ALL conditions must match (AND logic)
  conditions: [
    {
      id: crypto.randomUUID(),
      sourceBlockId: 'blk_vehicle_type',
      matchType: 'is-selected',
      sourceVariantIds: ['var_suv', 'var_sedan'] // ANY of these
    },
    {
      id: crypto.randomUUID(),
      sourceBlockId: 'blk_climate_pkg',
      matchType: 'is-selected',
      sourceVariantIds: ['var_climate_yes']
    }
  ]
};

3D Object Visibility Rules

Use targetScope: '3d' to show/hide 3D objects in the viewport without affecting the UI block. This lets you keep the option panel visible while controlling 3D representation independently.

// Hide the armrest 3D objects when "Minimalist" style is selected
const rule = {
  id: crypto.randomUUID(),
  action: 'hide',
  targetScope: '3d',
  target3dObjectNames: ['Armrest_Left', 'Armrest_Right'],
  targetVariantIds: [],
  operator: 'all',
  conditions: [{
    id: crypto.randomUUID(),
    sourceBlockId: 'blk_style',
    matchType: 'is-selected',
    sourceVariantIds: ['var_minimalist']
  }]
};

// A block can have BOTH a block-hide rule and a 3D-hide rule:
// Rule 1: Hide the block UI when condition X
// Rule 2: Hide 3D objects when condition Y

3D Visibility Rules

Use targetScope: '3d' with targetObjectIds to show/hide whole 3D objects, or targetScope: '3d-parts' with targetPartNames to show/hide individual mesh parts (sub-meshes) in the viewport.

// Hide decorative stitching and logo when "Plain" finish is selected
const rule = {
  id: crypto.randomUUID(),
  action: 'hide',
  targetScope: '3d-parts',
  target3dPartNames: ['stitching_detail', 'logo_emboss', 'button_caps'],
  targetVariantIds: [],
  operator: 'all',
  conditions: [{
    id: crypto.randomUUID(),
    sourceBlockId: 'blk_finish',
    matchType: 'is-selected',
    sourceVariantIds: ['var_plain']
  }]
};

// Use '3d' scope for whole objects, '3d-parts' for individual meshes.
// Both keep the UI block visible while controlling viewport visibility.

// Enterprise + Modular projects (modular option block) can target 3D parts
// across MULTIPLE objects in one rule via target3dPartsByObject — a map of
// model.fileName -> part names that supersedes the single-object
// target3dPartObjectName + target3dPartNames pair. Each object hides only the
// parts listed under its own key, so same-named meshes elsewhere are untouched.
const multiObjectRule = {
  id: crypto.randomUUID(),
  action: 'hide',
  targetScope: '3d-parts',
  target3dPartsByObject: {
    'Main_roof_3x3.glb': ['ridge_caps', 'flashing'],
    'Extra_roof_3x3.glb': ['ridge_caps_extra', 'flashing_extra']
  },
  targetVariantIds: [],
  operator: 'all',
  conditions: [{
    id: crypto.randomUUID(),
    sourceBlockId: 'blk_treatment',
    matchType: 'is-selected',
    sourceVariantIds: ['var_smooth']
  }]
};

Evaluate Conditions (Runtime)

POST/projects/:id/option-blocks/evaluate

Evaluate all conditional logic rules against a set of consumer selections. Returns which blocks and variants are visible.

const response = await fetch(BASE_URL + '/projects/proj_123/option-blocks/evaluate', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + accessToken,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    selections: {
      dropdownSelections: { 'blk_frame': 'black', 'blk_size': 'large' },
      selectMaterialSelections: { 'blk_fabric': 'linen' },
      checkboxSelections: { 'blk_accessories': ['cup-holder', 'monitor-stand'] },
      toggleSwitchSelections: { 'blk_armrests': 'with' },
      carouselSelections: {}
    }
  })
});

const data = await response.json();
// {
//   "success": true,
//   "results": [
//     { "blockId": "blk_001", "blockVisible": true, "hiddenVariantIds": [], "hidden3dObjectNames": [], "hidden3dPartNames": [] },
//     { "blockId": "blk_002", "blockVisible": true, "hiddenVariantIds": ["var_silk"], "hidden3dObjectNames": [], "hidden3dPartNames": [] },
//     { "blockId": "blk_armrest_color", "blockVisible": true, "hiddenVariantIds": [], "hidden3dObjectNames": ["armrest_left", "armrest_right"], "hidden3dPartNames": ["logo_emboss"] },
//     { "blockId": "blk_heated", "blockVisible": false, "hiddenVariantIds": [], "hidden3dObjectNames": [], "hidden3dPartNames": [] }
//   ]
// }

Continue reading