===================================== HowTo: Work with the Selection Buffer ===================================== .. include:: ..\version.h .. include:: howto-reference.h .. contents:: Table of Contents :backlinks: top .. The steps for creating a howto are, .. .. 1. Copy the howto-boilerplate to the desired filename (X). .. 2. Update the index-howto.txt file to have a reference to X. .. 3. Update the howto-reference.h file with the appropriate .. reference. ------- Preface ------- This document describes how to determine what the user has selected. Determining the user selection is done by inspecting the *selection buffer*. MineSightŪ Grail Embedded provides the grail.ms3d.selectionbuffer_ module as a means of reading the user's selection. This document will discuss inspecting the selection buffer with an example that will read all selected elements and report the element's areas to the MineSightŪ 3D Message Window. Related Links ------------- * `HowTo: Create an Embedded Script`_ * `Sample reportarea.py script`_ * grail.ms3d.selectionbuffer_ * grail.ms3d.element_ .. _Sample reportarea.py script : reportarea.py Assumptions ----------- It is assumed that you are familar with MineSightŪ 3D, and have an understanding of the basic mechanics behind python scripting. To execute a MineSightŪ Grail embedded script you must run the script inside the MineSightŪ 3D. Any script that references the grail.ms3d module, has this requirement. See `HowTo: Create an Embedded Script`_ for more details on MineSightŪ Grail Embedded scripting. --------------- Getting Started --------------- Reading the selection buffer requires you to do two things. 1. You must ensure that there are elements within the selection buffer. This can be accomplished by using the :f:`is_selection` function within the grail.ms3d.selectionbuffer_ module. This function will return 1 if the user has made any selections. 2. You have to retrieve the :c:`Element` objects from the selection buffer. This can be accomplished by using the :f:`get_elements` function within the grail.ms3d.selectionbuffer_ module. -------------------------------------------------- Example of Reporting the Area of Selected Elements -------------------------------------------------- As an example of working with the selection buffer we will consider reading the the user's selected :c:`Element` objects (see grail.ms3d.element_) and reporting the area of all objects--that have an area--to the message window. We will start by cloning the :file:`em-boilerplate.py` script found in the :file:`$(winexe)\\scripts\\samples` directory, and renaming the new script :file:`reportarea.py`. The first thing we will do is to is add some modules that we require to run this script. The following statements should be added alongside the other :d:`import` statements already within the script, .. Python:: from grail.ms3d import selectionbuffer from grail.ms3d import element from grail.ms3d import elementop The grail.ms3d.selectionbuffer_ module is used to query what the user has selected. The grail.ms3d.element_ module is used to check the types of elements that the user selected, and only report areas for polygons and surfaces/solids (i.e. shells). Finally the grail.ms3d.elementop_ module is used for its efficient area calculation operation designed to be used with :c:`Element` objects. The next step is to start writing out new code in the :f:`run_code` function of the new :file:`reportarea.py` script. We will start by adding a check that there is a selection. If there is we will call a new function call :f:`report_area`, which will read the selected :c:`Element` objects and report the areas. The new code should appear as, .. Python:: def run_code(): # (1) Check that there is a selection buffer. if selectionbuffer.is_selection(): report_area() else: # generates an error message string in the message window. sys.stderr.write("No objects selected.") def report_area(): # (2) Retrieve all elements from the selection buffer. els = selectionbuffer.get_elements() # (3) Traverse the selected elements and generate # a report to the message window. for el in els: name = el.get_name() # (4) If the element is unnamed give it a name. if not bool(name): name = "" # (5) Only compute areas for elements that are polygons # or shells. type = el.get_type() if type in [element.PolygonType, element.ShellType]: area = elementop.calc_area(el) print "%s : %.2f" % (name, area) else: print "%s : n/a" % (name) `View the complete reportarea.py script`__. .. __ : reportarea.py In the above script we do five things, 1. Verify that user has made a selection, if they have then we start to computing the areas for the selected elements. If they have not made a selection then we generate an error message and exit the function. 2. We retrieve all elements selected by the user and store it in a list called :d:`els`. 3. We traverse each element within the list and generate our area report. 4. For reporting purposes we will give unnamed elements a default name (""). 5. We only compute areas for elements that by definition have an area. If we encounter an element that does not have an area (for example a marker), we print a "n/a". ------- Details ------- The :file:`reportarea.py` script can be used for discussing a few points regarding the selection buffer, **Getting Selected Elements** Getting selected elements only returns those elements that are selected at the moment the :f:`selectionbuffer.get_elements` function is called. Therefore, if you allow user interaction, you may find that the state of the selection buffer can change depending on how the user modifies their selections. **Elements as Copies** All the elements selected by the :f:`selectionbuffer.get_elements` functions are copies of the ones that the user has selected. This was done as a safety precaution to prevent accidental overwriting of critical data. This means that any changes you make to selected elements does is will not reflect itself within the viewer. If you want to see the changes then it is recommended that you create a new Geometry MineSightŪ Object and store the modified elements within the new object (see grail.ms3d.datamanager_).