Python Assistant Prompts: Create Polyface Mesh


 

Prompt Used:

Can you write a script which implements a tool to create a polyface mesh 
(mesh with facets defined by points) based on user-clicked points defining each facet?

 

 

Python Assistant Generated Code:

from MSPyBentley import *
from MSPyECObjects import *
from MSPyBentleyGeom import *
from MSPyDgnPlatform import *
from MSPyDgnView import *
from MSPyMstnPlatform import *


class PolyfaceMeshCreator(DgnElementSetTool):
    """
    Tool to create polyface mesh elements using user-selected points for each facet.
    After three or more points are entered, a facet is created and added to the mesh.
    Reset to finish and add the mesh to the model.
    """
    def __init__(self, toolId=1):
        super().__init__(toolId)
        self.m_self = self
        self.m_Points = DPoint3dArray()  # Points for current facet
        self.m_Facets = []               # List of DPoint3dArray, one per facet
        self.activeModel = ISessionMgr.ActiveDgnModelRef

    def _OnRestartTool(self):
        PolyfaceMeshCreator.InstallNewInstance(self.GetToolId())

    def _OnResetButton(self, ev):
        # On reset, finish the mesh and add it to the model
        if self.m_Points and len(self.m_Points) >= 3:
            # Add last facet if user was in the middle of one
            self.m_Facets.append(DPoint3dArray(self.m_Points))
        if self.m_Facets:
            self.CreateMeshElement()
        self.m_Points.clear()
        self.m_Facets.clear()
        self._OnRestartTool()
        return True

    def _OnDataButton(self, ev):
        # Add point to current facet
        self.m_Points.append(ev.GetPoint())
        self.SetupAndPromptForNextAction()
        if len(self.m_Points) < 3:
            return False  # Need at least 3 points for a facet

        # If user clicks on the first point again, close facet
        if len(self.m_Points) > 3 and ev.GetPoint().AlmostEqual(self.m_Points[0]):
            # Remove duplicate last point
            self.m_Points.pop()
            self.m_Facets.append(DPoint3dArray(self.m_Points))
            self.m_Points.clear()
            NotificationManager.OutputPrompt("Facet closed. Start next facet or reset to finish mesh.")
            return False

        # If user double-clicks or presses Enter, treat as facet close
        # (Not implemented here, but could be added with additional event handling)

        # If user right-clicks, treat as facet close (handled in _OnResetButton)

        # If user presses Enter after 3+ points, close facet
        # (Not implemented here)

        # If user clicks, keep collecting points
        if len(self.m_Points) >= 3:
            # Optionally, allow user to close facet with a double-click or by clicking first point again
            pass

        return False

    def _OnPostInstall(self):
        AccuSnap.GetInstance().EnableSnap(True)
        super()._OnPostInstall()
        self.SetupAndPromptForNextAction()        

    def SetupAndPromptForNextAction(self):
        if not self.m_Points:
            NotificationManager.OutputPrompt("Click to enter first point of facet.")
        elif len(self.m_Points) < 3:
            NotificationManager.OutputPrompt("Click to enter next point of facet (at least 3 needed).")
        else:
            NotificationManager.OutputPrompt("Click to enter next point, or right-click/reset to close facet and start new one, or reset again to finish mesh.")

    def _OnDynamicFrame(self, ev):
        # Show dynamic preview of current facet
        if not self.m_Points:
            return
        tmpPts = DPoint3dArray(self.m_Points)
        tmpPts.append(ev.GetPoint())
        agenda = ElementAgenda()
        eeh = EditElementHandle()
        if len(tmpPts) >= 3:
            polyface = PolyfaceHeader.CreateVariableSizeIndexed()
            polyface.AddPolygon(tmpPts)
            if BentleyStatus.eSUCCESS == MeshHeaderHandler.CreateMeshElement(
                eeh, None, polyface, True, self.activeModel
            ):
                ElementPropertyUtils.ApplyActiveSettings(eeh)
                agenda.Insert(eeh)
        redrawElems = RedrawElems()
        redrawElems.SetDynamicsViews(IViewManager.GetActiveViewSet(), ev.GetViewport())
        redrawElems.SetDrawMode(eDRAW_MODE_TempDraw)
        redrawElems.SetDrawPurpose(DrawPurpose.eDynamics)
        for ag in agenda:
            redrawElems.DoRedraw(ag)

    def CreateMeshElement(self):
        # Build a polyface mesh from all collected facets
        if not self.m_Facets:
            return
        polyface = PolyfaceHeader.CreateVariableSizeIndexed()
        for facet in self.m_Facets:
            if len(facet) >= 3:
                polyface.AddPolygon(facet)
        eeh = EditElementHandle()
        dgnModel = self.activeModel.GetDgnModel()
        result = MeshHeaderHandler.CreateMeshElement(eeh, None, polyface, True, dgnModel)
        if BentleyStatus.eSUCCESS == result:
            ElementPropertyUtils.ApplyActiveSettings(eeh)
            eeh.AddToModel()
            MessageCenter.ShowInfoMessage("Polyface mesh created.", "", False)
        else:
            MessageCenter.ShowErrorMessage("Failed to create polyface mesh.", "", False)

    @staticmethod
    def InstallNewInstance(toolId=1):
        tool = PolyfaceMeshCreator(toolId)
        tool.InstallTool()


def main():
    # To activate the tool, call:
    PolyfaceMeshCreator.InstallNewInstance()


if __name__ == "__main__":
    main()

 

 

Python: Documentation | API Presentations | FAQs | GitHub | Samples | Wikis | Blogs