Roles and accounts

The ProductBuilder Ecosystem recognizes two types of accounts:

  • User
  • Organization

User accounts

A user account represents a person. With a User account, that person can create and save Projects for editing at a later time. To create a Project, the User needs a Viewer. User accounts can also be members of an Organization account.

Organization account

An Organization account represents a legal entity. Organization accounts can create and own Packages and Viewers. An Organization has at least one admin member, that is a User account. An Organization has one or more of the following roles:

  • Manufacturer
  • Dealer
  • Material supplier
  • Designer
  • Content creator

Manufacturer

Creates Products.

Dealer

Sells Products, either in a brick-and-mortar store or online.

Material supplier

Creates Materials, such as fabrics, that can be applied to Products.

Designer

Creates and maintains Templates and Themes for Organizations.

Content creator

Creates and maintains Packages for Manufacturers.

Product Family

Set of Products that are designed to be combined with each other, such as the elements of a sofa. Within our Ecosystem, Product Families are represented by Packages.

Examples

Moooi BFF Moooi BFF Product Family

Product

Physical object that is created and sold by a Manufacturer. A Product has a price which can be static or dependent on its configuration, territory and other parameters. Products are usually part of a Product Family.

Examples

Moooi BFF Moooi BFF Triple Element TE03




Dutch & Dutch 8c
Dutch & Dutch 8c in White/Natural finish

Package

A bundle of data that captures all relevant information about a Product Family and its members. Inside the package is a JSON file that defines a Block for each of the Products in the Product Family, including its dimensions, configuration options, etc.

Block

Representation of a single Product. Besides defining the 3D shape, the Block also defines how it can be combined with other Blocks through Connectors.

Examples

Below is a typical Block definition from a Package's index file.

{
      "id": "513cd38b-782a-4d3b-bbec-97538f8a050e",
      "name": "Chaise Longue CL01",
      "manRef": "CBFF-MCL0100",
      "thumbnail": "a36468b7-5af6-4293-8ade-c93c8a0f1d98",
      "categories": [
        "f4ec2b9e-78a2-4302-adcb-a025c1944574"
      ],
      "dimensions": {
        "x": 0.99,
        "y": 0.69,
        "z": 1.65
      },
      "dimensionsCenter": {
        "x": -0.165,
        "y": 0.345,
        "z": 0.165
      },
      "dimensionsImage": "7108f721-4d96-49e3-857b-2c119e4ebc24",
      "positionedMeshGroups": [
        {
          "id": "55afaf23-0dbe-4233-8e80-19f8ee39f573",
          "name": "legs left short side",
          "component": "7f35cb60-9f79-405d-846c-954441e16b84",
          "position": {
            "x": -0.58,
            "y": 0,
            "z": 0
          },
          "quaternion": {
            "_w": 1,
            "_x": 0,
            "_y": 0,
            "_z": 0
          }
        },
        {
          "id": "5396c746-c398-4e01-af2f-a1add9ae8b34",
          "name": "legs left",
          "component": "cbe9020b-9355-491b-88a6-be84d997d018",
          "position": {
            "x": -0.25,
            "y": 0,
            "z": 0
          },
          "quaternion": {
            "_w": 1,
            "_x": 0,
            "_y": 0,
            "_z": 0
          }
        },
        {
          "id": "d8b33c84-daec-4301-8603-f9f0e53fafbe",
          "name": "legs right",
          "component": "cbe9020b-9355-491b-88a6-be84d997d018",
          "position": {
            "x": 0.25,
            "y": 0,
            "z": 0
          },
          "quaternion": {
            "_w": 1,
            "_x": 0,
            "_y": 0,
            "_z": 0
          }
        }
      ],
      "positionedMeshes": [
        {
          "id": "cb1972e4-03b1-41ed-a081-1e68a317a634",
          "name": "sofa",
          "component": "bdf035f1-8ea5-448e-8d11-cfac4b0b4b3f",
          "position": {
            "x": 0,
            "y": 0.03,
            "z": 0
          },
          "quaternion": {
            "_w": 1,
            "_x": 0,
            "_y": 0,
            "_z": 0
          }
        }
      ],
      "connectors": [
        {
          "id": "798c6195-a4f2-4a7f-b568-dd079d4305a1",
          "name": "conRight",
          "position": {
            "x": 0.33,
            "y": 0.25,
            "z": 0
          },
          "quaternion": {
            "_w": 0.7071408,
            "_x": 0,
            "_y": 0.7070727,
            "_z": 0
          },
          "type": "2c5a24fb-03f2-413a-901b-9a3481592c20"
        },
        {
          "id": "245b9cdf-8efe-4d83-b5d7-246e2d04e575",
          "name": "conLeftFront",
          "position": {
            "x": 0,
            "y": 0.25,
            "z": 0.99
          },
          "quaternion": {
            "_w": 1,
            "_x": 0,
            "_y": 0,
            "_z": 0
          },
          "type": "af85b230-cb36-40fc-b7f9-116a34827f02"
        }
      ]
    }

Connector

Blocks can have Connectors. When two Blocks have compatible Connectors, they can be joined together in a Design.

Material

Physical materials, such as fabrics or wood are represented by digital materials simply called Materials.

Blocks can have different Materials applied to them in a Design.

Project

One or more Designs for a Space.

A Project can be saved, opened, edited and shared from the ProductBuilder Cloud.

Configuration

Specific arrangement of connected, materialized blocks. Users create Configurations by connecting Blocks together and applying Materials to them.

Design

One or more configurations that belong together, but are spatially separated.

Space

Details of a specific physical location, such as its dimensions.

Project Price

Price Class

Materials can have a Price Class. A Price Class can act as a price modifier or look-up category for a Product.

Territory

Price Zone

Product Price

The price of a Product in combination with a certain Material.

Embedding a Viewer

Template

ProductBuilder Iframe API V0

The Iframe API lets you embed a ProductBuilder Viewer on your website and control its behavior using JavaScript. This is our first attempt at creating such an API and we expect to make changes in the future, as first attempts are usually not final.

Using the API's JavaScript functions you can select presets; save and load projects; share designs; get a project's current price and take screenshots. You can also add event listeners that will execute in response to certain viewer events, such as a design update.

This guide explains how to use the Iframe API. It identifies the different types of events that the API can send and explains how to write event listeners to respond to those events. It also details the different JavaScript functions that you can call to control the viewer as well as the viewer parameters you can use to customize the viewer.

Requirements

The user's browser must support the HTML5 postMessage feature. Most modern browsers support postMessage.

Getting started

The sample HTML page below creates an embedded viewer that will load a Package and display the first preset. The numbered comments in the HTML are explained in the list below the example.

<!DOCTYPE html>
<html lang="en">

   <body>

        <!-- The package id is in the URL -->
        <iframe width=800 height=600 id="pbapp" src="https://live.productbuilder.nl/demo"></iframe>

        <script type="module" async="true">

            import PBIframeApi from 'https://cdn.productbuilder.nl/iframe-api.v0.js';

            // the iframe to communicate with
            const iframe = document.getElementById( 'target' );

            // create the control object
            const viewer = new PBIframeApi( iframe );

            // wait for the connection to be made
            await viewer.connectionPromise;

            // start controlling the viewer
            await viewer.selectPreset( 0 );

        </script>
    </body>
</html>

Initialisation

A viewer can simply be embedded by embedding an Iframe with the appropriate URL. To control the API, the iframe-api script must be loaded from https://cdn.productbuilder.nl/iframe-api.v0.js. The script is a module and must be loaded as such. It exports the PBIframeApi class, which can be instantiated by providing a reference to a ProductBuilder Iframe DOM element. The new PBIframeApi object will attempt to connect to the code inside the Iframe by checking whether the

  • content is indeed a ProductBuilder viewer
  • versions are compatible
  • origin of the parent is allowed by the viewer

The PBIframeApi object has a property called connectionPromise which is should be awaited. If any of the above checks fail, the promise is rejected resulting in an error which you can catch and deal with gracefully. If the promise resolves, the connection has been made and it is now safe to start communicating with the viewer.

Operations

Change the locale

Only possible after the viewer is connected to the ProductBuilder cloud.

viewer.setLocale(locale:String):Boolean

Get the id of the current project

viewer.projectId():String

Get the slug of the current project

viewer.projectSlug():String

Share a project

Creates a copy with a different id/slug and make it readonly.

viewer.shareProject():Object<string,string>

Save the current project to the ProductBuilder cloud

viewer.saveProject():Object<string,string>

Load a project from the cloud.

viewer.loadProject(identifier:String):Object<string,string>

Get the configurators in the current design

Returns an array of objects with the configurator id and pkg id.

viewer.listConfigurators():Array<Object<string,string>>

Get the presets of a package

Returns a flat list of objects with the preset id and package id.

viewer.listPresets(pkgId:String):Array<Object<string,string>>

Take a screenshot

Returns a DataURI of a screenshot of the current camera angle.

viewer.screenshot():String

Select a preset

Update the current design by changing it into a preset.

viewer.selectPreset({ configuratorId:String, presetId:String }):Boolean 

Get project price

Returns the current price object if the viewer is connected to the ProductBuilder cloud.

viewer.price():Object 

Call template specific methods

viewer.ui(data:any):any 

List the available packages

Returns an array of {id:string} objects.

viewer.listLoadedPackages():Array<Object<string,string>>