Python

Simple Element Modifier

The Element Pick and Modify tool is a simple tool that inherits from the MicroStation Python DgnElementSetTool. When you pick an element you have the opportunity to change a vertex in method _OnElementModify.

The code here is borrowed from the example delivered with MicroStation Python …

..\Examples\Microstation\DgnTool\ElementModifier.py

ElementPickAndModify Class

class ElementPickAndModify(DgnElementSetTool):
    def __init__(self, toolId: int):
        """
        Initialize the ElementPicker.

        param toolId: The ID of the tool.
       """
        DgnElementSetTool.__init__(self, toolId: int) # C++ base's __init__ must be called.
        self.m_isDynamics = False
        self.m_ev = None
        self.m_self = self # Keep self-referenced. This variable is used by the base class DgnElementSetTool.

Method _OnPostLocate

First we must verify that the chosen element is suitable for modification. It should be a linear DGN element such as a line or line-string. The right place to perform that check is in method _OnPostLocate …

def _OnPostLocate(self, path: HitPath, cant_accept_reason: str)->bool:
	"""
	Handle post-locate event to determine if the element can be accepted for modification.

	:param path: The path of the located element.
	:param cant_accept_reason: The reason why the element cannot be accepted.
	:returns: True if the element can be accepted, False otherwise.
	"""
	if not DgnElementSetTool._OnPostLocate(self, path, cant_accept_reason):
		return False

	eh = ElementHandle(path.GetHeadElem(), path.GetRoot())
	curve = ICurvePathQuery.ElementToCurveVector(eh)

	# Accept elements that are open paths with one or more linear segments (ex. line or linestring).
	if curve==None or (not curve.IsOpenPath()):
		return False

	primitive_type = curve.HasSingleCurvePrimitive()
	if primitive_type == ICurvePrimitive.eCURVE_PRIMITIVE_TYPE_Line or primitive_type == ICurvePrimitive.eCURVE_PRIMITIVE_TYPE_LineString:
		return True

	return False

Method _OnElementModify

The purpose of Element Picker is simple: when you pick an element you have the opportunity to change a vertex in this method …

def _OnElementModify(self, eeh: EditElementHandle)->BentleyStatus:
    """
    Modify the given element.

    :param eeh: The element to be modified.
    :returns: The status of the modification.
    """
    # NOTE: Since we've already validated the element in OnPostLocate and don't support groups/selection sets we don't have to check it again here.
    locate_point = DPoint3d()
    curve = ICurvePathQuery.ElementToCurveVector(eeh)

    self._GetAnchorPoint(locate_point)

    # Get curve location detail from accept point.
    location_detail = CurveLocationDetail()
    if not curve.ClosestPointBounded(locate_point, location_detail):
        return BentleyStatus.eERROR

    # Get the closest vertex from the curve location detail.
    n_closest_vertex = self.get_closest_vertex(location_detail)
    primitive = curve[0]

    # Update closest vertex on line/line string with current button location.
    if primitive.GetCurvePrimitiveType() == ICurvePrimitive.eCURVE_PRIMITIVE_TYPE_Line:
        segment = primitive.GetLine()
        segment.SetPoint(self.m_ev.GetPoint(), n_closest_vertex)
        primitive = ICurvePrimitive.CreateLine(segment) # Replace line primitive with a new primitive with modified point.
    elif primitive.GetCurvePrimitiveType() == ICurvePrimitive.eCURVE_PRIMITIVE_TYPE_LineString:
        points = primitive.GetLineString()
        points[n_closest_vertex] = self.m_ev.GetPoint()
        primitive = ICurvePrimitive.CreateLineString(points) # Replace linestring primitive with a new primitive with modified point.

    # Give the element's handler a chance to update itself from the modified curve vector.
    edited_path = eeh.GetHandler()

    if edited_path != None and edited_path.SetCurveVector(eeh, curve) == BentleyStatus.eSUCCESS:
        return BentleyStatus.eSUCCESS

    # Handler didn't choose to update itself, create a new element to represent the modified curve vector.
    return DraftingElementSchema.ToElement(eeh, curve, eeh, eeh.GetModelRef().Is3d(), eeh.GetModelRef())

LA Solutions Examples

You'll find Python examples written by LA Solutions on these pages, starting here.

Visit the LA Solutions' State Machine examples Download page.


Questions

Post questions about MicroStation programming to the MicroStation Programming Forum.