Skip to content

Preview

Python offers the possibility to draw some geometry objects as preview. These objects are only drawn in the viewport during the runtime of a PythonPart, but are not being saved in the model.

To implement a preview in a standard PythonPart, append the objects, that should be created as preview, to the preview_elements property of the CreateElementResult object.

Example

In this example we create two cubes, from which the left one is just a preview object and the right one is the one, that should be created.

def create_element(build_ele, doc):
    common_props = AllplanBaseElements.CommonProperties()
    common_props.GetGlobalProperties()

    preview_props = AllplanBaseElements.CommonProperties(common_props)
    preview_props.Color = 6 #(1)!

    right_polyhedron = AllplanGeo.Polyhedron3D.CreateCuboid(AllplanGeo.Point3D(),
                                                            AllplanGeo.Point3D(500,500,500))

    left_polyhedron = AllplanGeo.Polyhedron3D.CreateCuboid(AllplanGeo.Point3D(-500,0,0),
                                                        AllplanGeo.Point3D(0,500,500))

    preview_ele_list = [AllplanBasisElements.ModelElement3D(preview_props, left_polyhedron)] #(2)!
    model_ele_list = [AllplanBasisElements.ModelElement3D(common_props, right_polyhedron)] #(3)!

    return CreateElementResult(elements=            model_ele_list,
                               preview_elements=    preview_ele_list)
  1. To distinguish the preview from the actual object, we assign a red color to it.
  2. These elements are just use for preview and will not be created. Note, that AllplanElements must be appended to the list (in this case a ModelElement3D). Pure geometry is not enough.
  3. These elements will be created in the DF, when PythonPart is terminated

To implement a preview in an Interactor PythonPart use the DrawElementPreview function. Depending on the desired behavior, choose the right member function of the Interactor class to implement it. To achieve similar behavior as in the Standard PythonPart, the preview must be generated with every mouse movement, so it should be implemented in the process_mouse_msg function.

Example

In this example, the objects in the preview_ele_list are used to create a preview. The preview is created at the point indicated with the mouse.

def process_mouse_msg(self,
                      mouse_msg: int,
                      pnt      : AllplanGeometry.Point2D,
                      msg_info : Any) -> bool:

    input_pnt = self.coord_input.GetInputPoint(mouse_msg, pnt, msg_info).GetPoint() #(1)!

    if self.coord_input.IsMouseMove(mouse_msg):  #(2)!

        placement_matrix = AllplanGeometry.Matrix3D()
        placement_matrix.SetTranslation(AllplanGeometry.Vector3D(input_pnt)) #(3)!

        AllplanBaseElements.DrawElementPreview( \
            doc =            self.coord_input.GetInputViewDocument(),
            insertionMat =   placement_matrix,
            modelEleList =   preview_ele_list, #(4)!
            bDirectDraw =    False,
            assoRefObj =     None)

    return True
  1. We are getting a Point3D object out of the mouse message to move the preview objects into the position, where the mouse points. Because it is implemented in the process_mouse_msg function, it will be executed with every mouse movement making the preview follow the mouse.
  2. With this statement, the Preview object will be generated only when mouse is moved. In case of click, nothing will happen. In our example, the self.coord_input contains the CoordinateInput object. It is passed to the create_interactor function, when the PythonPart is initialized.
  3. The placement_matrix will move the preview objects from (0,0,0) to the input_pnt.
  4. The preview_ele_list contains AllplanElements which should be drawn as preview.

Preview symbols

The PythonPart preview can be extended by using preview symbols. These are displayed in every Allplan viewport and have a fixed size, regardless of the zoom level. The preview symbols can be created using the class PreviewSymbols. This object represents a container with all preview symbols. You add new symbol using the member functions.

In a standard PythonPart it is enough to pass the PreviewSymbols object to the property preview_symbols of the CreateElementResult object.

Example

We take the previous example of two cubes and append an additional text as a preview symbol, to make it readable in all views.

def create_element(build_ele, doc):
    common_props = AllplanBaseElements.CommonProperties()
    common_props.GetGlobalProperties()

    preview_props = AllplanBaseElements.CommonProperties(common_props)
    preview_props.Color = 6

    right_polyhedron = AllplanGeo.Polyhedron3D.CreateCuboid(AllplanGeo.Point3D(),
                                                            AllplanGeo.Point3D(500,500,500))

    left_polyhedron = AllplanGeo.Polyhedron3D.CreateCuboid(AllplanGeo.Point3D(-500,0,0),
                                                           AllplanGeo.Point3D(0,500,500))

    preview_symbols = PreviewSymbols()
    preview_symbols.add_text(text=              "Preview text",
                             reference_point=   AllplanGeo.Point3D(0,250,0),
                             ref_pnt_pos=       TextReferencePointPosition.CENTER_RIGHT,
                             height=            50.0,
                             color=             6,
                             rotation_angle=    AllplanGeo.Angle())

    preview_ele_list = [AllplanBasisElements.ModelElement3D(preview_props, left_polyhedron)]
    model_ele_list = [AllplanBasisElements.ModelElement3D(common_props, right_polyhedron)]

    return CreateElementResult(elements=            model_ele_list,
                               preview_elements=    preview_ele_list,
                               preview_symbols=     preview_symbols)

In an interactor PythonPart use the draw method from the class PreviewSymbols to draw the preview symbol in the viewport.

Example

We take the previous example and only append an additional text as a preview symbol.

def process_mouse_msg(self,
                      mouse_msg: int,
                      pnt      : AllplanGeometry.Point2D,
                      msg_info : Any) -> bool:

    input_pnt = self.coord_input.GetInputPoint(mouse_msg, pnt, msg_info).GetPoint()

    preview_symbols = PreviewSymbols()
    preview_symbols.add_text(text=              "Preview text",
                             reference_point=   AllplanGeo.Point3D(0,250,0),
                             ref_pnt_pos=       TextReferencePointPosition.CENTER_RIGHT,
                             height=            50.0,
                             color=             6,
                             rotation_angle=    AllplanGeo.Angle())

    if self.coord_input.IsMouseMove(mouse_msg):

        placement_matrix = AllplanGeometry.Matrix3D()
        placement_matrix.SetTranslation(AllplanGeometry.Vector3D(input_pnt))

        AllplanBaseElements.DrawElementPreview( \
            doc =            self.coord_input.GetInputViewDocument(),
            insertionMat =   placement_matrix,
            modelEleList =   preview_ele_list,
            bDirectDraw =    False,
            assoRefObj =     None)

        preview_symbols.draw(placement_matrix,
                             self.coord_input.GetViewWorldProjection())
    return True

Example

Usage of the preview symbols is implemented in the example DrawPreviewSymbols located in:

  • …\etc\Examples\PythonParts\BasisExamples\General\DrawPreviewSymbols.pyp
  • …\etc\PythonPartsExampleScripts\BasisExamples\General\DrawPreviewSymbols.py

Library preview

Library preview

A preview of a PythonPart can be shown in the Allplan Library in two locations:

  • preview viewport - above the content of the directory a small collapsible window displays the geometry of a PythonPart. The user can rotate or zoom in the viewport or even change display style.
  • thumbnail - directly in the library directory PythonParts are displayed as a simple raster image.

Preview viewport

To display the preview elements representing the PythonPart in a preview viewport, creation of these elements must be implemented in the create_preview function.

Info

The implementation looks the same in both standard PythonPart and in interactor PythonPart - the function must be implemented directly in the script (not as a method of an interactor class). In a standard PythonPart however, if the function is missing, the result of create_element will be used as a preview instead. In an interactor PythonPart nothing will be created.

Example

Let's create a cylinder as a preview for our PythonPart. It should be 3 m high and has a radius of 50 cm. The implementation is very similar to the implementation of the create_element function:

def create_preview(_build_ele: BuildingElement,  #(1)!
                   _doc      : AllplanElementAdapter.DocumentAdapter):

com_prop = AllplanSettings.AllplanGlobalSettings.GetCurrentCommonProperties()
com_prop.GetGlobalProperties()

axis     = AllplanGeo.AxisPlacement3D(AllplanGeo.Point3D(3000, 500 , 0))
cylinder_geo = AllplanGeo.BRep3D.CreateCylinder(axis, 500, 3000)
model_ele_list = [AllplanBasisElements.ModelElement3D(com_prop, cylinder_geo)]

return CreateElementResult(elements = model_ele_list) #(2)!
  1. Similar to create_element function, a BuildingElement object with the Parameters of the PythonPart is passed to the function. However, the passed parameter values are always the default ones, defined in the .pyp file. In this case we don't use these parameters, the cylinder dimensions are hard coded.
  2. Only the elements included in the elements property of the CreateElementResult data class will be used to generate a preview. Preview symbols e.g., will not be included.

Thumbnail

To display a thumbnail in the library, a .png file with the image must be provided. The location and name of the .png file must be the same as the location and name of the .pyp file. The size of the bitmap is freely selectable. If the file does not exist, a default icon will be displayed.

Settings

By default, the preview for the PythonPart is optimized for performance. For this reason, the isometric curves of the BReps are not drawn. This can be disabled/enabled by:

  • typing Alt+V
  • calling the function SetShowFullPreview

    pythonparts_settings = AllplanSettings.PythonPartsSettings.GetInstance()
    pythonparts_settings.SetShowFullPreview(True)