Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Updates
Updates to this manual will be issued as replacement pages and a new Update History Sheet complete with instructions
on which pages to remove and destroy, and where to insert the new sheets. Please ensure that you have received all
the updates shown on the History Sheet.
All updates are highlighted by a revision code marker, which appears to the left of new material.
Suggestion/Problems
If you have a suggestion about this manual or the system to which it refers please report it to the training department at
All rights reserved. No part of this publication may be reproduced or used in any form or by any means (graphic,
electronic, mechanical, photocopying, recording, taping, or otherwise) without written permission of the publisher.
1 Introduction.............................................................................................................................................. 5
1.1 Objectives ......................................................................................................................... 5
1.2 Prerequisites for training course .................................................................................... 5
1.3 Training methods ............................................................................................................. 5
1.4 Overview............................................................................................................................ 5
1.5 Duration............................................................................................................................. 6
1.6 Using this document ........................................................................................................ 6
3
4
Chapter 1
1 Introduction
After completing the Vitesse Basic course, the user is prepared to create Vitesse macros. This course is designed to
introduce the advanced Tribon Vitesse functionalities, requiring some programming experience.
1.1 Objectives
The aim of the course is to provide the knowledge required for creating advanced Tribon Vitesse macros. After
completing the course, the user should be in a position to control Tribon system using Tribon Vitesse and to manage the
assembly information..
The objective is to become familiar with the Tribon Vitesse functions in the area of:
The following skills are required from at least one person in each group:
A copy of the training project must be installed for this training, prior to the trainer arriving.
1.4 Overview
Vitesse Basic course has introduced the concept of Tribon Vitesse, the Python programming language and basic utility
and user interface functionalities, including Data Extraction and Drafting. When using Tribon system in an interactive
way, the designers are using the system in a way predefined by Aveva Solutions. It is, however, possible to change the
default behaviour of the Tribon application using triggers. When set up properly, they tell Tribon applications to behave
differently, in a way specific to the customer. It is possible, for example, to let Tribon store information in the customer’s
databases, to verify, if the given functionality is allowed to be used, or not, etc.
5
User-defined macros can be made accessible to the designers through the appropriate items in the application’s menu
or through the buttons in the toolbars. Such user-defined menus and toolbars can be also defined for the specified
interactive Tribon application, so that each department of the Design Office has its own set of enhancements.
Tribon databanks store many attributes for the model objects. It is, however, possible to design custom attributes, that
can be assigned to the objects, and stored. These attributes can be later examined and updated, if necessary. The
standard display of the object’s properties can be enhanced with additional information coming from the custom
attributes assigned to the objects. They can be shown together with the standard information on existing or on separate
property pages.
This course also introduces the participants to the assembly management through Tribon Vitesse. We will learn, how to
manage the assembly tree, the objects collected to the assemblies, and the assembly information stored in the
assembly database. Designers from both Hull and Outfitting departments will benefit from this part of the training,
although the actual introduction to the Vitesse for Hull and Outfitting takes place in a separate course.
Finally, we will learn the model utilities, able to investigate the environment of the hull and outfitting objects.
1.5 Duration
2 days
All examples will be displayed as bold text in the Courier New font, and the program output will be indented to the
right with respect to the user input. System prompts should be bold and italic in single quotes, i.e. 'Choose function'.
L Additional information
Refer to other documentation
Larger examples and solutions to the exercises have not been included in the Training Guide, but can be found in
the folder 'Vitesse Advanced Training' under SB_PYTHON of the training project. References to these examples are
annotated with:
Refer to the training examples
In order to keep examples short, the necessary import statements have been generally removed, and some missing
part of the code are annotated with the ellipsis '…' and a comment describing, what has been omitted.
6
Chapter 2
2.1 Triggers
Triggers are Python functions which are called when certain events happen in the Tribon system. By using them, the
developer can adapt many aspects of the application's behaviour to the client's requirements. A trigger is usually
implemented in a Python file having a name predefined for each event. The Tribon environment variable
SBB_TRIGDIR should be set up to point to the directory where the trigger scripts are located. In a default installation,
this variable points to the \Vitesse\Trigger folder below the Tribon installation root folder.
L Note: Some of the triggers are used by the Tribon standard functionality. User additions can be made to these
triggers, but the existing implementation should be left intact for the Tribon standard functionality to work properly.
Each trigger exists in two flavours: the pre-trigger, and the post-trigger. This is defined as two functions: pre() and
post(). The pre() function is called before the Tribon event is performed. It can do some preparations, check the
conditions required for the corresponding Tribon functionality to be executed properly. If something goes wrong, it can
decide to abort the event, so that the Tribon functionality will not be executed.
The post() function is called after the Tribon event, unless the processing of the event failed, has been interrupted, or
the pre() function returned a status code preventing the execution of the event. The arguments to be passed to these
functions depend on the given trigger.
Triggers are implemented in such a way, that only interactive events will result in a trigger call. For example, the
interactive File-Open command will initiate a call to the trig_draft_dwg_new trigger, while using the
kcs_draft.dwg_new() Vitesse function will not activate any trigger.
There is a possibility for a trigger to control the execution of the Tribon event by means of a number of predefined trigger
status codes, specified in the section 2.2. If an unknown return code is issued or if the Python interpretation fails for a
Pre-trigger, the Tribon event will be interrupted.
An example trigger script is presented below. It does nothing particularly useful, apart from notifying the user about the
trigger's activity, and displaying the list of arguments passed to the trigger. In order to test the trigger, simply copy the
code given below to the SBB_TRIGDIR folder under the name specific to the trigger, that you want to test.
import kcs_util
import kcs_ui
⇒ def pre(*args):
return ShowParameters(args, "Pre-trigger called!")
⇒ def post(*args):
return ShowParameters(args, "Post-trigger called!")
The table below lists the available triggers. Some of them are already defined in the standard Tribon delivery. Please be
careful not to deactivate or change the default trigger functionality, because it is essential for the Tribon system. The
details are given in the Tribon Vitesse User's Guide. For brevity, the triggers are grouped in families. Each trigger from
the given family has the name with the common prefix (e.g. 'trig_draft_dwg_new' for the trigger specified as 'dwg_new')
7
Trigger Notes
DRAFTING TRIGGERS – 'trig_draft_' prefix
Fired every time a Drafting based application is started. User Interface customisation
init
should be done in a post() trigger function.
Fired when using File/New command. The pre() function is called, before the user is
dwg_new
prompted for a drawing form name.
Fired when using File/Open command. The pre() function is called, before the user is
dwg_open
prompted for a drawing name.
dwg_close Fired when using File/Close command.
cable_route Fired when using the commands from the Cable/Route submenu.
8
Trigger Notes
cway_comp_bent Fired when using Cable Way/Material/Bent part command.
9
The following example prevents you from overwriting an existing drawing, when using the File Æ Save command in the
menu or the corresponding button on the toolbar.
The code given below should be stored under the name of 'trig_draft_dwg_save.py' in SBB_TRIGDIR folder.
def pre(*args):
if kcs_draft.dwg_current():
if kcs_draft.dwg_exist(kcs_draft.dwg_name_get()):
kcs_ui.message_confirm("Drawing already exists in the databank!")
⇒ return kcs_util.trigger_abort()
return kcs_util.trigger_ok()
L The above trigger function will not be called, when a Vitesse script calls the kcs_draft.dwg_save() function.
The trigger documentation can give you further information regarding the effect after returning the given trigger
status code.
There are triggers (e.g. trig_draft_insert_model_filter), which are supposed to return some data to the
program. In this case the pre() and post() functions should return not the trigger status code alone, but a list, whose first
element is the trigger status code, and the remaining elements are the data to be returned to the program.
The solutions to the exercises can be found in the 'Vitesse Advanced Training' folder under
SB_PYTHON in the training project
where triggerName is the name of the trigger, as specified in the table on pages 8-9, functionType is one of the
following constants determining the type of the registered trigger function: kcs_util.kcsPRE_TRIGGER, or
kcs_util.kcsPOST_TRIGGER. Finally function must be a callable object – the reference to the function, being
registered.
The example below registers the function beforePrint() as the pre() function for the trigger occurring, when the drawing
is to be printed.
10
def beforePrint(*args):
kcs_ui.message_confirm("Please make sure, the printer is turned on!")
return kcs_util.trigger_ok()
⇒ kcs_util.register_trigger("trig_draft_dwg_print", \
kcs_util.kcsPRE_TRIGGER, beforePrint)
The registered function remains active for the given trigger, until the application is terminated, or the given function is
unregistered, as shown below …
kcs_util.unregister_trigger("trig_draft_dwg_print", \
kcs_util.kcsPRE_TRIGGER, beforePrint)
where similar arguments must be supplied, as when the function was registered.
L When unregistering trigger functions, make sure you refer to exactly THE SAME function, as when the function has
been registered. In rare situations, when you redefine the function after it has been registered, you need to recover
the original function reference by calling the kcs_util.get_registered_triggers() (see below) and
use it in the call to the function kcs_util.unregister_trigger().
All currently registered trigger functions can be obtained using the kcs_util.get_registered_triggers()
function which returns a dictionary consisting of key:value pairs, where the key is the trigger name, and the value is a
tuple consisting of two lists – the first contains references to the pre() functions, and the second contains references to
the post() functions for this trigger.
⇒ regTriggers = kcs_util.get_registered_triggers()
print "*** Registered triggers:"
for triggerName in regTriggers: #loop over the dictionary keys
pre, post = regTriggers[triggerName]
displayFun(triggerName, "Pre", pre)
displayFun(triggerName, "Post", post)
When handling the given pre- or post-trigger, Tribon executes first the default trigger function, defined as the pre() or
post() function in the script having the trigger name, and stored in the SBB_TRIGDIR folder. Then, if the default
trigger does not interrupt the event, Tribon continues with the execution of the registered functions for this trigger in the
order of their registration. If any of these functions interrupts the event, the remaining functions are not executed.
L You can register more than one function for the given trigger.
The kcs_util module provides a set of functions, that detect the running application, returning 1 when the given
application is detected, or 0, if another application is currently running.
11
kcs_util.app_nesting() - is this Hull Plate Nesting?
kcs_util.app_pipe() - is this Pipe Modelling?
kcs_util.app_structure() - is this Structure Modelling?
kcs_util.app_ventilation() - is this Ventilation Modelling?
The above functions can also be used to code application-specific actions in the trigger functions by using them in the
if … elif … else … statement.
⇒ if kcs_util.app_basic_design():
… #Code specific to Basic Design
else:
… #General code for other applications
• Configurable notes (_TBhook_ConfigNote.py) – placing customised notes in the drawing with non-standard
shape and contents;
• Plane panel scheme layout (_TBhook_PPanScheme.py) – allows to define, how the statements of the plane
panel scheme are displayed in the Scheme Editor. The hook functions control how the statement's text should
be formatted. All basic text formatting facilities available in the HTML language are at your disposal (line
breaks, and font attributes: bold, italics, underline, etc.);
• Customised brackets (_TBhook_CustBracket.py) – defines custom brackets as bracket panels;
• Customised holes (_TBhook_CustHole.py) – defines non-standard hole shapes for planar hull modelling;
• Customised notches (_TBhook_CustNotch.py) – defines custom notch shapes for planar hull modelling;
• Customised part names (_TBhook_CustPartName.py) – defines custom part names, which are then used
instead of the standard Tribon part naming rules;
• Automatic naming of plane panels (_TBhook_AutoPanelName.py) – if defined, automatically generates plane
panel names, when the panel is created in the interactive Hull Planar Modelling application;
• Formula retrieval (_TBhook_Formula.py) – returns the values for non-standard drawing rules, currently
supported only in the Tribon Nesting system.
L Details about each of the Vitesse hooks can be found in the Tribon documentation and in the example hook scripts,
that you can find in PYTHONPATH folder. They can be expanded by adding your own desired functionality.
12
Chapter 3
Typically, the customisation should be made in the Initialise Drafting Post trigger (trig_draft_init trigger, post() function),
which is fired after the application has started, and initialised itself. The changes made to the application's user interface
are valid for the current session only. In order to make them permanent, the trigger script must be available at all times,
so that the same changes would be applied the next time the application is run. The trigger can establish the contents of
the menus and toolbars, but the toolbar location is saved and restored from the registry – this is the only information
preserved across sessions. The functions are made available in the Python program by the insertion of the statement:
import kcs_gui
The kcs_gui module defines the 'error' variable, holding the information about the kind of error that happened during
the execution of the module's functions.
If the folder SB_PYTHON\Lib is appended to PYTHONPATH, it is possible to import this script and use its functions,
when referring to menu functions or toolbars in the Initialise Drafting Post trigger. The example code shown below
demonstrates, how to add the SB_PYTHON\Lib folder to PYTHONPATH programmatically.
import kcs_util
sb_python = kcs_util.TB_environment_get("SB_PYTHON")
folder = sb_python + "\\Lib" # SB_PYTHON\Lib folder
import sys
⇒ sys.path.append(folder) #add 'folder' to PYTHONPATH ...
import kcs_gui_drafting #...to let import find the module
FileNew_ID = kcs_gui_drafting.file_new()
tbControl_ID = kcs_gui_drafting.toolbar_controls()
Of course, the numerical ids can be used in the program directly, without using the above-mentioned script and the
functions therein. It may be even safer to follow this practice, since the numerical ids are less likely to be changed in
future releases, than the names of functions defining them.
Example: after running the Drafting application, we can find the script kcs_gui_drafting.py in the Lib subfolder under
the one defined by the SB_PYTHON Tribon environment variable. It contains many function definitions, among which we
can read:
def file_new():
return 33036
which means, that the id of the File/New menu function in the Drafting application is 33036.
13
3.2 Menu functions
Each application contains the main menu, and a number of pop-up menus being child menus to either the main menu, or
some other pop-up menu. This hierarchical structure can be accessed and manipulated using the functions specified
below. When accessing the application's menu, we begin by getting the handle to the main menu:
editDeleteMenu = kcs_gui.menu_get(editMenu, 2)
When specifying the submenu's position within the parent menu, we count from 0
upwards, taking into account both active and inactive items, and separator line. That's
why the position of the first separator is 1, and of the 'Delete' submenu is 2.
L The menu handles obtained with the function kcs_gui.menu_get() or kcs_gui.menu_add() are
temporary, and become invalid, when the application becomes idle, for example, when a dialogue box is displayed
afterwards (e.g. using kcs_ui module). In such case they have to be obtained again, if they are still required.
The branches of the application’s menu tree terminate with the items, that do not represent a child submenu, but a
simple command, like 'Text' on the picture to the right, or separators. Trying to use the kcs_gui.menu_get()
function on these items raises an exception. They can be accessed with the kcs_gui.menu_item_get() function,
as shown below:
The kcs_gui.menu_item_get() function returns a tuple, where the first item is the item's caption, and the second
– the ID of the associated Tribon function. The ampersand character '&' in the item's caption indicates, that the next
character should be used as the accelerator key for this menu item. If the accessed item is not a simple item, but a
submenu, the second element of the resulting tuple is –1. Called for the separator item (the last example), this function
returns an empty string as the caption, and 0 (ZERO) as the function ID. When the requested menu position is not valid,
an exception is raised with kcs_gui.error set to 'kcs_CaptionError'.
By using recursively the above functions, the programmer is able to retrieve the whole application's menu structure with
the item's captions, and function ids. It is also possible to add a new menu (submenu):
The result is the handle to the new empty menu, attached to the parentMenu at the given Position. The items existing
so far at the given Position and above are shifted one position forwards to make room for the new item. Then you can
add items (and submenus) to submenu as the parent menu, as shown below
14
#add a user menu item – script "MyCommand" at position 2
⇒ funID = kcs_gui.menu_item_usr_add(parent, 2, "User-defined &script", \
"MyCommand", "Launches the user command")
#add a submenu at position 3
⇒ submenu = kcs_gui.menu_add(parent, 3, "SubMenu")
#… add items to the submenu
In the first example, the number 33036 is the valid function ID of the File/New standard command. The second example
shows, that in order to add a separator, you have to provide a negative function ID (caption is irrelevant).
When adding a user command (third example), instead of function ID you have to provide the script name and the
description text, which is displayed on the status bar, when the menu item is highlighted. The script name should be
given without a path and extension. As the result, you get the function ID of your user-defined script, assigned by the
system, which can be used next to refer to this user-defined script as if it were a standard function, when creating other
menu items or toolbar buttons.
L Scripts containing the code for non-standard menu items should be placed in PYTHONPATH, and should contain
the run() function, that will be invoked, when the menu item is selected.
There is a limit of the user-defined functions in the system. An exception is raised, if this limit is reached. In order to
install more user-defined functions, create a single menu item, that displays a selection dialogue box, launching
various user-defined functions.
L By placing the '&' character in the Caption string you define the character following the '&' character as the
accelerator key for this menu item. The '&' character is not displayed in the menu item's caption.
Instead of adding or inserting new menu items, it is also possible to update an existing menu item.
You can use this function, for example, to translate the Caption texts of the menu items to your own language. Existing
menus or menu items can be removed using the function
kcs_gui.menu_remove(Menu, Position)
L Any future Service Pack or new release of Tribon system can change the layout of application's menu. You should
not rely on existing menu item's position numbers being preserved, when you write code, that updates the
application's menu. The same applies to the toolbars.
In the original release of Tribon M3, the presence of this additional main menu item had to be taken into account, when
calling the kcs_gui.menu_item_get() function, for determining the position (index) of an item on the main menu.
This is no longer necessary in Tribon M3 SP1, where the existence of the viewport's icon menu is always ignored by the
kcs_gui module functions.
Since the menu layout can change between releases, create a module gui_utils (store it in PYTHONPATH) with the
functions:
locateMenuItem(parent, captionFragment, startIndex = 0), that locates the item, whose caption
contains the given captionFragment. Searching is performed among the parent menu items, starting from an item with
the index startIndex. The result should be a tuple (index, caption, functionID), if the item is found, or None, if the item
has not been found. If captionFragment is an empty string, a separator should be located.
locateMenu(parent, captionFragment, startIndex = 0), that performs the similar search, but
returns the tuple (index, caption, submenu handle), if found.
15
Exercise 6: Updating the application’s menu
Add the 'User' menu for the Drafting
application only, as shown here. The
user-defined commands (after the sepa-
rator) should simply display a message
telling that they have been called.
Additionally, please remove the 'Print
Preview' command from the 'File' menu.
Hint: Use functions from your new
gui_utils module (Exercise 5).
'Print Preview'
command removed!
3.3 Toolbar functions
In the previous section we have seen, that in order to manipulate the application's menu, we have to get the handle to
the menu, and use it to manipulate its items and submenus. Tribon Vitesse follows this idea also for the toolbars. In
order to get the handle to an existing toolbar, we have to use the function
After creation, the toolbar is empty, and should be filled with buttons, performing the desired functions. We can also add
buttons to existing toolbars.
1⇒ kcs_gui.toolbar_button_std_add(toolbar, 0, 33036, \
"C:\\Tribon\\M3\\Icons\\001.ico", \
"New drawing", "Create new drawing")
2⇒ kcs_gui.toolbar_button_std_add(toolbar, 1, -1, "", "", "")
3⇒ funID = kcs_gui.toolbar_button_usr_add(toolbar, 2, "MyCommand", \
"C:\\Tribon\\M3\\Icons\\002.ico", \
"User-defined script", "Launches the user command")
The first example adds at position 0 the toolbar button performing the standard function File Æ New (function ID =
33036). We have to provide the path to the icon bitmap file (.ico or .bmp format), the button tooltip and message to be
displayed in the status bar, when this button is highlighted.
The second example adds a separator at position 1. Function ID should be negative, and the remaining arguments are
irrelevant.
The third example adds at position 2 the non-standard toolbar button executing the user-defined Vitesse script given as
the third argument. The remaining three arguments have the same meaning, as in example no. 1. The function returns
the function ID of the user script, assigned by the system, which can be used next to refer to the user-defined script, as if
it were the standard Tribon function.
L Scripts containing the code for non-standard toolbar buttons should be placed in PYTHONPATH, and should
contain the run() function, that is invoked, when the toolbar button is clicked.
There is a limit of the user-defined functions in the system. An exception will be raised, if this limit is reached. In
order to install more user-defined functions, create a single toolbar button, that displays a selection dialogue box,
launching various user-defined functions.
It is also possible to remove an existing button from the toolbar using the function
kcs_gui.toolbar_button_remove(Toolbar, Position)
16
Exercise 7: Adding user-defined toolbar
Modify the program from Exercise 6, so that instead of the 'User' menu, a new toolbar named 'My toolbar' is created with
the same contents. As bitmaps, use any supported .bmp or .ico files, that you can find on your system. You can also use
the icons provided in the 'Icons' folder under SB_SYSTEM.
Application is the name of the application to be displayed in the title bar. Format is the specification of the application's
title, and can contain the following format specifiers.:
The application's title will have the form <Format> - <Application>. Example:
produces the title "Drawing EX_DRAFT on project TPP – Drafting" for drawing "EX_DRAFT" on project TPP.
• 'RETURN'
• 'NUMPAD0', 'NUMPAD1', …, 'NUMPAD9'
• 'MULTIPLY', 'ADD', 'SUBTRACT', 'DIVIDE'
• 'DECIMAL'
• 'F1', 'F2', …, 'F12'
The additional system keys are defined as bit flags: Alt – 1, Ctrl – 2, Shift – 4. This gives us 8 possible combinations:
kcs_gui.accelerator_add('F2', 2, 33036)
defines, that pressing the combination Ctrl + F2 should invoke the File Æ New command (function ID = 33036). It is also
possible to pass the function ID of user-defined functions, once you obtain their function ID when adding a menu item or
toolbar button.
Implement the Initialise Drafting Post-Trigger, that makes the changes in the application menu, as in Exercise 6, creates
a toolbar as in Exercise 7, and defines the F10 key as the shortcut to displaying the whole drawing (Zoom Auto).
17
18
Chapter 4
4 User-defined attributes
User-defined attributes provide a method of storing user data in the Tribon Product Information Model. Tribon Vitesse
provides a module called kcs_att for defining and manipulating the attributes. In order to use it, the program must
contain the statement:
import kcs_att
Exceptions raised by the functions from the kcs_att module are reported by the kcs_att.error variable, containing
the description of the error. The Tribon Toolkit Preference program is used for creating attribute templates. Various
attribute templates are organised in categories. An attribute template describes the kind of data that is stored in an
attribute. An attribute template can contain the following information:
• Integer numbers
• Real numbers
• Strings
• Date and time information
• References to an external file
Usually, before dealing with user-defined attributes in a Vitesse program, you should make necessary category and
template definitions by using the Tribon Toolkit Preferences program. See User's Guide for details.
Several of the functions described below use a Target parameter. The target parameter should be one of the following:
For some model types, it is allowed to attach user-defined attributes to both the model and parts within the model. In
these cases, setting Model.PartId to zero indicates the model itself.
category and template are the names of the category and attribute template, as defined in the Tribon Toolkit
Preferences applications. If successful, the attribute is created with all data set to the default values, and attached to the
target. If target is a model object, it becomes locked, and you must take care of releasing the lock after finishing the
work with the target's attribute, as shown below:
An attribute can be also obtained by copying another attribute, possibly from another target.
The copy of the attribute att1 is attached to the given target and returned as att2.
A target can have many attributes attached. The example below shows, how to iterate over the target's attributes:
19
iterator = 0 #Attribute loop index (0 to 9)
⇒ att = kcs_att.attribute_first_get(target, 1, iterator) #READ-ONLY access
while att:
… #analyse the attribute 'att'
⇒ att = kcs_att.attribute_next_get(iterator) #Get next attribute
The function kcs_att.attribute_first_get() initiates the loop over the target's attributes. The third, optional
argument defines the iterator – the index of a concurrently running loop over the attributes. The default value is 0, but if
you need to run another loop over the attributes, make sure you select another iterator value (up to 9).
The second argument of the kcs_att.attribute_first_get() function determines the type of access to the
target's attributes: 1 – read-only access (see example above), and 0 – updating allowed (see example below).
While iterating over the target's attributes we need to identify the attributes, so that we find the one we want to update or
analyse. Tribon Vitesse allows us to identify the template, from which the given attribute has been created.
Tribon Toolkit Preferences application creates for each attribute template a script kcs_att_<category>.py,
located in the SB_PYTHON folder, defining the alias functions, that return identifications strings (UUID) of the attribute
templates. These functions have names of the form <customer>_<category>_<template>, where the <customer> part is
the value of the SB_CUSTOMER Tribon environment variable (converted to lowercase!).
Example: for template 'status' in category 'pipe' we will have the function yard_pipe_status() in the module
kcs_att_pipe.py, assuming that the value of SB_CUSTOMER variable is 'yard'. You can use this module in your scripts
after copying it to PYTHONPATH.
While iterating over the attributes you can check the type of the attribute with the kcs_att.attribute_is()
function by comparing the attribute with the template's alias function.
import kcs_att_pipe
alias = kcs_att_pipe.yard_pipe_status()
… #while iterating over the attributes, we get the attribute 'att'
⇒ if kcs_att.attribute_is(att, alias):
… #attribute found, work on it …
Once we have found the right attribute, what can we do with it? We can manipulate the attribute's data …
The above pattern written for integer data can be easily adapted for other data types, according to the table below:
20
The title of the data is fetched from the template definition and can be used for messages concerning the attributes. The
Date type of data requires a little bit more attention. The time is expressed as two integer numbers:
•
st
number of full seconds since the midnight, 1 of January 1970, and
• number of milliseconds
The function kcs_att.date_get() returns thus a tuple containing the above two integer numbers. The last two
arguments of the function kcs_att.date_set() are the new values of these two numbers. Example:
import time
… #We update the date-type data at index 'n' of the attribute 'att'
⇒ sec, ms = kcs_att.date_get(att, n) #get seconds and milliseconds
seconds = sec + 0.001*ms #time in seconds as a real number
timeStr = time.strftime("Time: %Y-%m-%d %H:%M:%S", \
time.localtime(seconds))
kcs_ui.message_confirm(timeStr) #Display original date attribute
sec += 3600 #Move the time forward by 1 hour
⇒ kcs_att.date_set(target, att, n, sec, ms) #Set new date attribute
The Reference data type holds the path to an external file, whose type (extension) is defined in the attribute's template
as the default value.
Using the above functions allows you to manipulate the data stored in the attribute directly. Tribon Vitesse provides also
the function
kcs_att.attribute_edit(target, Readonly)
which displays a dialogue box identical to the one available through the interactive function Tools Æ Data Management
Æ Attributes, where on the User-defined page you gain access to the object's user-defined attributes with the ability to
add the attributes, and modify or remove existing ones. Setting Readonly to 1 allows the user to view the attributes,
without being able to modify them. The value of 0 unlocks the possibility to modify the attributes.
This is the simplest way to edit the target's attributes. The drawback is, that it gives access to ALL target's attributes, not
only the user-defined ones, and you cannot control, what the user will do with the target's attributes.
It is possible also to remove an existing attribute from the target by using the function
kcs_att.attribute_detach(target, attribute)
L Using kcs_att.attribute_detach() function invalidates all iterators pointing to the given attribute!
After attaching an attribute to the target, its template may have been modified using the Tribon Toolkit Preferences
application. It is possible to check, if the attribute matches the current definition of its template by calling the function
where convert determines, what should be done, if the attribute does not match the template. The possible values are:
The attribute conversion consists in creating a new attribute, basing on the current definition of the template, and
copying the data from the old attribute with the matching title. The other data will take their default values. The result is
an integer indicating the result of verification:
-2 – attribute matches the template, but one or more data titles are different
-1 – attribute matches the template, but the UUIDs (template identification strings) are different. This means,
that the template has been deleted and recreated with the same category and name
0 – attribute does not match the template
1 – attribute matches the template
The attribute's category and template names can be retrieved using the function
21
All modification to the target's attributes, if target is a modal object, must be terminated by calling the function
kcs_att.model_save(target)
Otherwise, the model object will be locked on the databank. We recommend to use try: … finally: …
construction to guarantee that the lock will be released.
try:
… #modify model object's attributes
finally:
⇒ kcs_att.model_save(target)
Use Tribon Preference Toolkit application to create the category 'pipe' and the template 'status' with the following data:
Create the function update_status(model), that updates the status data for the pipe given as the Model class
instance (model argument). If the 'status' attribute is not found, it should be created. The user should be able to edit the
integer and string data of the attribute. If successful, the date should be set to the current time (use time module).
As an example, let's take a look at the properties for pipes. Several properties are standard: the assembly, component
name, component description, etc.
22
The scripts prop_time.py and prop_attr.py located in the 'Vitesse Advanced Training' folder under
SB_PYTHON contain the actual code for this example.
import time
def get(*args):
return time.ctime()
def get(*args):
model = args[0]
return [model.Name, model.Type]
See the script prop_attr.py for a more advanced example, using user-defined pipe properties.
Compound properties with different columns must be displayed on different property tabs. The column header for the
given tab should be defined also by the Vitesse script with the get() function, returning the list of column headers for
the tab. The script name in this case should have the form <tab_name>_tab_<object_type>.py, after removing all
space characters from tab_name and object_type strings. The script itself should be located in SB_PYTHON folder, In
our example with the Tabular properties tab, the script should have the name Tabularproperties_tab_Pipe.py and
should contain the following function
def get(*args):
return ["Property", "Stage", "Unit", "Unit description"]
For our simple example displaying model name and type, the headers could be defined as:
def get(*args):
return ["Property", "Name", "Type"]
L Property tabs, that do not specify the headers (e.g. there is no script <tab_name>_tab_<object_type>.py in
SB_PYTHON), will have the standard header consisting of "Property" and "Value" columns.
If the get() function of the compound property returns less data items, than expected by the tab's header definition,
the missing columns will have empty strings as values. If there are more data items, than expected, the excessive data
items are simply ignored.
23
24
Chapter 5
5 Assembly management
For management of the assembly information, Tribon Vitesse provides the module kcs_assembly. Additionally,
assembly-related functions exist in many other Vitesse modules, concerning modelling outfitting objects.
5.1 Introduction
By using the functions in the kcs_assembly interface the Vitesse program is able to:
There are three types of identification of the assembly nodes, and the kcs_assembly module supports all of them.
• internal names (e.g. '_AS0000001234') – unique node names automatically generated by the system,
• user given names (e.g. 'SBPH3') – they must be unique within the parent assembly. The root assembly has a
fixed name of '-',
• path name (e.g. '-BL4-WD23-SBPH3') – concatenation of user given names of all superior assembly nodes,
separated by '-' character.
Some functions will use the Python classes given below as input or output parameters:
• KcsAssembly.Assembly - The class holds information about assembly.
• KcsAssemblyKeyInItem.AssemblyKeyInItem - The class holds information about assembly key-in item.
They store many attributes of the assembly key-in item, and the assembly itself.
For the description of the classes, class methods etc. please refer to the system documentation Tribon M3
Developer's Toolkit - Vitesse - Python Classes - Assembly or to the source files of the given classes
The kcs_assembly module stores the error information in the kcs_assembly.error variable, when an exception is
raised during execution of the module's functions.
⇒ if kcs_assembly.assembly_exist('-STAN-TONY'):
… #work on existing assembly –STAN-TONY
The result is 1 if the given assembly exists, or 0 if it does not. Instead of the assembly path name, you can also provide
its internal name. You may want to use this function to check, whether it is necessary to create the given assembly.
if not kcs_assembly.assembly_exist('-STAN-NEW'):
⇒ kcs_assembly.assembly_new('-STAN', 'NEW')
The first argument is the path or internal name of the parent assembly, and the second – the user name of the new
assembly to be created under the given parent assembly.
L For creating the top-level assembly, supply the string '-' as the parent assembly argument to the function
kcs_assembly.assembly_new(). Trying to call this function to create an existing assembly DOES
NOTHING – no exception is raised.
25
The kcs_assembly module implements the idea of the 'current' assembly, and functions working on the current
assembly. Before any changes are made to an assembly, it must be made active either by activating an existing
assembly or creating a new one. Of course, no assembly can be active, when trying to make an assembly current.
⇒ kcs_assembly.assembly_activate('-STAN-NEW')
try:
… #work on the current assembly
⇒ kcs_assembly.assembly_save()
except:
kcs_ui.message_confirm("Errors encountered: " + kcs_assembly.error)
⇒ kcs_assembly.assembly_cancel()
After finishing the work on the current assembly, don't forget to save the changes using the function
kcs_assembly.assembly_save(). On error, the changes should be discarded and the assembly deactivated
using the function kcs_assembly.assembly_cancel().
L After creation, the assembly is not yet active! In order to make it active, you need to call the function
kcs_assembly.assembly_activate() after kcs_assembly.assembly_new().
What can we do with the current assembly? We can move it to another parent …
kcs_assembly.assembly_move(newParent)
prop.SetDescription("New description")
prop.SetPlanningUnit("PLU01")
⇒ kcs_assembly.assembly_properties_set(prop) #set assembly properties
L The prop variable above is an instance of the KcsAssembly.Assembly class. See the documentation for the
possible attributes and methods of accessing them.
NOTE: Functions assembly_properties_set() and assembly_properties_get() require that the
_TB_ASS_DEFAULT object is stored on the assembly databank (SB_ASSDB). This object (and the level
definitions) can be created with the utility program ph015.
We may also instruct the system to calculate the weight and COG for the current assembly. The calculated values are
stored in the assembly, and can be retrieved later using the kcs_assembly.assembly_properties_get()
function.
Finally, we may also collect the model objects to the current assembly, and decollect them from the current assembly.
This will be explained in section 5.4.
In general, you can assume, that functions from the kcs_assembly module, that do not have the assembly name as
one of their arguments, work on the current assembly, and assume, that an assembly is active.
So far, we have been using the function kcs_assembly.assembly_properties_get() without any argument,
so that it returned the properties of the current assembly. You can, however, provide the assembly name. Then the
returned information will concern the assembly given as an argument.
prop = kcs_assembly.assembly_properties_get('-STAN-NEW')
26
kcs_assembly.assembly_delete('-NEW')
If successful, this function removes the assembly given as an argument from the assembly databank, together with all
subordinate assemblies and model references.
⇒ internalName = kcs_assembly.assembly_internal_name_get('-STAN')
print "Internal name:", internalName
Internal name: _AS0000000003
⇒ pathName = kcs_assembly.assembly_path_name_get(internalName)
print "Path name:", pathName
Path name: -STAN
L The function kcs_assembly.assembly_internal_name_get() raises an exception if called for the root
assembly, expressed as '-'.
The path name of the sub-assembly can be formed from the path name of the parent assembly and the user name of
the sub-assembly.
For every assembly, except for the root assembly, you can get the internal and path names of its parent using the
function
where assName is either the internal or path name of the assembly, whose parent assembly is to be found. Each
assembly can have many subassemblies. It is possible to get the names of the subassemblies, as shown below:
⇒ res = kcs_assembly.assembly_sub_get(assName)
for pathName, internalName in res:
kcs_ui.message_noconfirm("Path name %s, internal name %s" % \
(pathName, internalName))
The example above shows how to get the names of subassemblies of the assembly assName. The result is a list of
2-element tuples consisting of the path name and internal name of the subassembly. If you want to explore the deeper
levels of the assembly tree, you need to call recursively the function kcs_assembly.assembly_sub_get()
providing the names of the assemblies to find their child assemblies.
L If the function kcs_assembly.assembly_sub_get() returns an empty list, the analysed assembly has no
subordinate assemblies.
The use of the recursive generator function (new feature of Python 2.3!), shown below, allows to traverse and retrieve
the WHOLE assembly tree. The node names are presented in this order: subassemblies first, siblings next.
27
5.4 Managing assembly contents
Each assembly (except from the root assembly) can contain references to the model objects or to the so called key-in
items. Tribon Vitesse handles these two categories of assembly contents with the appropriate class instances:
modelRefList = kcs_assembly.assembly_model_ref_get(assName)
keyinRefList = kcs_assembly.assembly_keyin_ref_get(assName)
modelRefList is a list of Model class instances, representing model object references, and keyinRefList – a list of
AssemblyKeyInItem class instances, representing the key-in item references.
We can also collect model object references to the current assembly and decollect them using Tribon Vitesse.
kcs_assembly.assembly_activate("-STAN")
try:
model1 = KcsModel.Model("pipe", "KCS-WW11")
⇒ kcs_assembly.model_collect(model1)
model2 = KcsModel.Model("struct", "FOUND1")
⇒ kcs_assembly.model_decollect(model2)
kcs_assembly.assembly_save()
except:
kcs_assembly.assembly_cancel()
Of course, you may also set the PartType, PartId, and ReflCode attributes of the Model class instance to specify
a MODEL PART to be collected/decollected. Most often the model objects will be selected by the user, through
indication in the drawing or Data Extraction queries. We can easily do the same for the key-in items.
kcs_assembly.assembly_activate("-STAN")
try:
keyin1 = KcsAssemblyKeyInItem.AssemblyKeyIntItem()
keyin1.SetItemType("key-in component")
keyin1.SetName("AG01COMP")
… # set other properties of 'keyin1'
⇒ kcs_assembly.model_collect(keyin1)
keyin2 = KcsAssemblyKeyInItem.AssemblyKeyIntItem()
keyin2.SetItemType("key-in part")
keyin2.SetName("AG01PART")
… # set other properties of 'keyin2'
⇒ kcs_assembly.model_decollect(keyin2)
kcs_assembly.assembly_save()
except:
kcs_assembly.assembly_cancel()
Various properties of key-in items can be set. See the AssemblyKeyInItem class documentation for details.
28
for docRef in docRefList[:]:
if docRef.GetType() == 'vitesse': #Remove 'vitesse' references
⇒ kcs_assembly.document_reference_remove(docRef)
L After making changes to the document references, don't forget to save the current assembly.
Tribon system is able to manage document references attached to various objects, not only to assemblies. They can
have the following types:
Create an application, which will create new assembly (first level) and set some of its properties:
• Description
• Building strategy (1-st line)
• Orientation
Create an application, which will collect hull panels to the given assembly:
• The user should be prompted to key in assembly name
• Then – indicate panel(s) on a drawing
29
30
Chapter 6
Currently, the model, for which the "touching" test can be performed is restricted to the following types:
• "equipment",
• "struct",
• "pipe",
• "ventilation",
• "cable".
Adjacent objects are considered touched, when they overlap in space, at least partially. In order to perform this test, you
need to have a drawing open with the appropriate model objects drawn in the model views.
It is also possible to perform the similar "touching" test on hull objects, i.e. find all parts of the outfitting objects of the
given type, that "touch" the given hull object.
This time, we are looking for specific outfitting object's parts (pipes in the above example). The second argument defines
the type of the outfitting object, which may be one types mentioned above in the description of the function
kcs_model.model_hull_contact(). The Range defines the additional distance from the model's surface, that
will be taken into account in the collision check.
31
32