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?
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