The TBC database can be thought like a file system where the top level (like C:\ in a file system) is a class called Project. Each object may have properties and also contain other objects. There is a TML that shows this tree structure (ViewProjectData).
This is a view of a new project. The top node in the tree is the "Project". The project contains many members in its list of objects. One of those is the "LayerCollection". As you might guess, this is the container where Layers are stored. Inside the layer collection object are two layers. When a new project is created, two layers are also created (layer "0" and layer "Points"). You can see those two layers under the layer collection.
You can see other collections under the project object. Collections like TextStyleCollection, LineStyleCollection, etc.
There is a collection under Project named WorldView. That is the collection where most objects a user creates are added. Things like alignments, surfaces, polylines, etc. Objects created in other views (like sheet or profile) are not stored here.
Each object has a property called SerialNumber. This is a unique unsigned int that is used to reference objects. The ViewProjectData macro shows the SerialNumber at the end of the object name. The serial number of the layer collection is "6". Many objects have a layer property. To set the objects layer, you set the Layer property to the serial number of the layer.
To create an object you just need to call the "Add" method on the container that should hold the object. So if we want to add a linestring to the WorldView container, the python code would be like this:
wv = self.currentProject[Project.FixedSerial.WorldView]
ls = wv.Add(clr.GetClrType(Linestring))
This linestring would exist in the database but untill you add geometry, it will not display.
If you run TBC and create the objects you want to add/modify in a macro, you can then use the ViewProjectData macro to see the objects name and what collection it was placed in.
For example, if you create a circle in TBC, then ViewProjectData will show you a Trimble.Vce.ForeignCad.Circle was added to WorldView. In this case, the assebly namespace is Trimble.Vce.ForeignCad and the class name is Circle.
The easiest way to find the properties of an object is to use the Visual Studio tool Object Bowser tool.
Using the Object Browser
The Object Browser allows you to review all available classes defined in the DLLs in your project to see their properties, methods, and events. This helps you understand what classes are, where they are stored, and what you can do with them. In addition, you can see the procedures and constants that are available from object libraries in your project. You can use the Object Browser to find classes to use.
Note: You can easily display online Help by pressing F1 as you browse.
You should set the Browse option to "Custom Component Set" and use the "..." button to add TBC assemblies. Browse to the C:\Program Files (x86)\Trimble\Macros SDK folder to find the assemblies.
Using Common Controls
Most TBC commands use 'custom controls' to allow you to select and enter values for coordinates, stations, layers, etc. Currently, the available controls include:
AngularEdit (enter/pick two points for an angle)
BearingEdit (enter/pick two points for a bearing)
ComboBoxEntityPicker (select an object from a list)
CoordinateEdit (enter/pick a coordinate)
DistanceEdit (enter/pick two points for a distance)
ElevationEdit (enter an elevation)
MemberSelection (select multiple objects)
NumericEdit (general numeric control)
OffsetEdit (enter/pick two points for an offset)
SelectEntity (select one object)
StationEdit (enter/pick a station)
StreamingCoordinateEdit (click-and-drag to create a line of CAD points)
VerticalAngleEdit (enter/pick two points in a profile view for a vertical angle)
LeftRightEdit (select the side of a line looking down the line from the starting station)
Layer (select a layer from a list)
LineStyle (select a dashed or other style for lines from a list)
TextStyle (select a typeface, font, and styles from a list)
Commands with UI
Dialog box style
Can create window directly or create class that inherits from Window
Typically, a command frame docks the UI. When you run a docked command, the program creates a C# helper class that is basically a native C# command with the properties of the Python script inside it. That's how the Python code gets integrated.
If you have a WPF command, you start with the outside Window co and then you start adding other controls (typically a grid and a stacker) which helps specify where other components are.
A “helper” class is created that holds the basic framework of the command. This command uses WPF for UI layout.
By default, the xaml file has a grid with a stacker panel for the macro command’s use. The StackPanel goes inside the UI of the command that is running.
The macro must define a class that inherits from the wpf StackPanel control
At Runtime. wpf.LoadComponent is used to to read xaml file and create UI controls.
Several predefined functions are available. If these function are defined, they will l be called.
Using WPF, you can change fonts, size, etc.
All of this is using IronPython.
Command Data Class
These properties are assigned to each “Command”:
Command Name (defaults to Key)
Command Caption (defaults to Name)
If True, this hides the command, such as when it it not ready to use or only for internal diagnostics. This precludes the macro command from appearing in the UI, but you can type the key on the Command line to open it.
The bitmapped 'icon' for placing the command on a ribbon or toolbar; if you do not supply one, a default icon will be inserted
Note: The icon you supply should be 19x19 pixels.
If True, the function “SetupExecute()” will be called when the application starts. Typically, no project is loaded at this time, so this is usually used to modify the ribbon. (You will rarely set this to True, unless you wanted e.g., .)
If True, command is always enabled, whether a project is open or not, e.g. a macro for reconfiguring the layout of ribbon tabs and panes.
Name of Class in your script that defines what the UI controls when command shows UI in the command frame. Just leave as empty string if the command does not use the command frame UI. If this is defined, a command wrapper is created, UI is called and placed in it. (used often)
Properties (for Ribbon placement)
Specify the key of a tool after which the command will be inserted. If the value is string.Empty, the tool is inserted as the first item in the menu. If the value is null or the key is not found, the tool is added to the bottom of the menu.