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)
- To distinguish the preview from the actual object, we assign a red color to it.
- 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.
- 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
- 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. - 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. - The
placement_matrix
will move the preview objects from (0,0,0) to theinput_pnt
. - 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
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)!
- 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. - 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