Custom-made Model View Options object

This post is a follow-up article of the basic MVO how-to, showing a way of setting up a custom model view options object for a custom library.

Example .lcf can be downloaded here.

Generally, there are 3 design ideas of object-MVO connections:

  • the object has a normal parameter with possible values, extended with the value option “by MVO”, and only acts according to the MVO if this parameter is set to “by MVO” value. In this case, acting to the MVO is a “secondary” feature of the object.
  • the object is directly linked to act as the MVO says, without any additional parameter. MVO is the main process driver here.
  • similar to the previous one, with an additional “override MVO” parameter within the object to add the possibility to ignore MVO settings. This is very similar to the first version, but the accent is on the MVO in this case, not on the object.

Depending on the functionality you want to move to the MVO panel, one has to be chosen from these design methods.

Step 1: creating the MVO object

Create and save a new library part, give a suitable, easy-to-recall name to it. You will have to remember it later.
Important to use the Library Global Settings subtype, found here:

  • General GDL Object/Documentation Element/Drawing Symbol

The subtype will only add the “A” and “B” parameters to the parameter list by default, letting you fill the rest up with custom function parameters.
Turn off the “Placeable” option in the object Detail page (same way as with macros).
mvo_custom_step1
If this new object is saved to an external folder, make sure to add it to the active libraries. After a reload, the MVO palette will look like this:
mvo_custom_afterfirstload
Now you have a blank panel with a generic name listed among the other existing MVO pages.
Note: the order of appearance of the GDL MVO objects depends on the GUID of the items, alphabetically. If you are unsatisfied with the result, try a different ID (“Save as…”).

Step 2: customizing the MVO object

You might want to add a more specific title to the new panel, and maybe the default height needs to be adjusted to your needs as well (width is fixed, 600 pixels).
Open your MVO object (since it is not placeable, use the Report window to type in the name of the object, then select, and hit the hotkey combo for “Open object…” for quick access).
Go to the User Interface script, add a title and content to your liking:

! ------------------------------------------------------------
! set basic variables
! ------------------------------------------------------------
_yCurr		= 5
_dy		= 25		! generic line spacing		

_totalWidth	= 600		! fixed value to match the exisiting panels
_totalHeight	= 4* _dy	! calculate the height from line spacing
_stDialogTitle	= `Settings of Example Library Parts (ARCHICAD Library 20)`

! ------------------------------------------------------------
! set title and height for the custom MVO panel
! ------------------------------------------------------------
ui_dialog _stDialogTitle, _totalWidth, _totalHeight

The result looks like this:
mvo_custom_step2

Step 3: connecting the MVO function with a placeable object

From this point on, it is up to you how you design the contents.
In the example package, the placeable object has the following integer parameter and value list:

! in parameter script of the placeable object
values{2} "iPlanSymbol"	SYMBOL_CIRCLE, `Circle`,
			SYMBOL_CROSSEDSQUARE, `Crossed Square`,
			SYMBOL_MVO, `by MVO`

To support the “by MVO” value, the MVO object needs a matching parameter with appropriate values (integer type):

! in parameter script of the MVO object
values{2} "iPlanSymbolMVO"	SYMBOL_SQUARE, `Square`,
				SYMBOL_TRIANGLE, `Triangle`

Note: make sure to inicialize the constant variables in the Master script the usual way (see example file).
The 2 value lists do not need to be the same, or contain all possible values each. The value list division or contents should depend on the purpose of the whole development.
In this example, “Square” and “Triangle” are only available through MVO option, can not be set individually from the object’s parameter list, while the rest of the options are object-exclusive only.
However, in the placeable object’s scripts, all possible outcomes should be handled in the same system, since the symbol drawing is created in the object’s 2D script.
In case you have several objects depending on the same MVO parameter, create a macro to set up the value definitions for the actual drawing.

Put “planSymbolMVO” parameter onto the MVO panel (the parameter list of an MVO libpart is not accessible, User Interface is the only option here for display):

! in UI script of the MVO object
ui_style 0, 1
ui_outfield `Plan Symbol Type`, 0, _yCurr, 150, 15
ui_style 0, 0

ui_infield{4} "iPlanSymbolMVO", 155, _yCurr-4, 120, 19,
			8, "",
			0, 0,
			0, 0, 0, 0,
			"", `Square`, SYMBOL_SQUARE,
			"", `Triangle`, SYMBOL_TRIANGLE

mvo_custom_step3
All you have to do now is to script the codes to handle the incoming values:

! ------------------------------------------------------------
! possible 2D symbols to cover:
! - square
! - crossed square
! - circle
! - triangle
! ------------------------------------------------------------

DRAW_SQUARE	= 1
DRAW_TRIANGLE	= 2
DRAW_CROSSEDSQUARE = 3
DRAW_CIRCLE	= 4

! set default for drawing
_iSymbolDraw = DRAW_CIRCLE

! set symbol to draw according to "iPlanSymbol"
if iPlanSymbol = SYMBOL_MVO then
	_reqPlanSymbolMVO = 0
	_bSuccess = LIBRARYGLOBAL ("myCustomMVO", "iPlanSymbolMVO", _reqPlanSymbolMVO)
	if _bSuccess then
		if _reqPlanSymbolMVO = SYMBOL_SQUARE then
			_iSymbolDraw = DRAW_SQUARE
		endif
		if _reqPlanSymbolMVO = SYMBOL_TRIANGLE then
			_iSymbolDraw = DRAW_TRIANGLE
		endif
	else
		text2 0, 0, "WTF"
	endif
else
	if iPlanSymbol = SYMBOL_CIRCLE then
		_iSymbolDraw = DRAW_CIRCLE
	endif
	if iPlanSymbol = SYMBOL_CROSSEDSQUARE then
		_iSymbolDraw = DRAW_CROSSEDSQUARE
	endif
endif

Once the drawing variable is set according to the MVO and object parameters, create the scripts to do the actual drawing:

! ------------------------------------------------------------
! draw symbols according to _iSymbolDraw value
! ------------------------------------------------------------
pen gs_cont_pen

if _iSymbolDraw = DRAW_SQUARE then
	gosub "drawSquare"
endif
if _iSymbolDraw = DRAW_TRIANGLE then
	gosub "drawTriangle"
endif
if _iSymbolDraw = DRAW_CIRCLE then
	gosub "drawCircle"
endif
if _iSymbolDraw = DRAW_CROSSEDSQUARE then
	gosub "drawSquare"
	gosub "drawCrossing"
endif

The rest of the script in the example package contains the different subroutines for the different symbols.

Summary

Creating a globally usable MVO function takes care and consideration. Once you have started to use MVO in your objects, removing the function in an update without breaking compatibility in not an option.
Also important to note the following:

  • a custom MVO object and the library parts responding to it must be both loaded in the plan. Best is to create an .lcf package which contains all of them.
  • any package containing objects and corresponding custom MVO object within the same .lcf can be uploaded to BIMcomponents.com
  • value coming from the MVO should never be saved in any object parameter: it would cause parameter inconsistency within the object instance due to the multiple possible values coming from the MVO views within one planfile.
  • an MVO library part can not be subject to migration
  • an object set to “by MVO” can not be migrated backwards to a state where this option was unavailable (parallel MVO settings exist within the planfile, migration can handle exactly one version only, as with any normal parameter)