class ExportODB(AFXDataDialog): """Export ODB with meshio.""" [ID_CLICKED_FILE_BUTTON] = range(AFXDataDialog.ID_LAST, AFXDataDialog.ID_LAST + 1) def __init__(self, form): def atoi(text): return int(text) if text.isdigit() else text def natural_keys(text): ''' alist.sort(key=natural_keys) sorts in human order http://nedbatchelder.com/blog/200712/human_sorting.html (See Toothy's implementation in the comments) ''' return [atoi(c) for c in re.split(r'(\d+)', text)] """Set up the initial dialog and connect Buttons to actions.""" self.form = form # find current viewport currentViewport = session.viewports[session.currentViewportName] # assign odb file from current viewport self.odb = currentViewport.displayedObject # get file name and path self.odbFileNameFull = self.odb.path self.file_name = AFXStringTarget() AFXDataDialog.__init__(self, form, "Export ODB", 0, DIALOG_ACTIONS_SEPARATOR) FXLabel(self, "This plugin exports the ODB with Meshio.") self.variables = [] for var in currentViewport.odbDisplay.fieldVariables.variableList: self.variables.append(var[0]) self.variables.sort(key=natural_keys) hf_selectors = FXHorizontalFrame(self) gb_instances = FXGroupBox(hf_selectors, "Instance", FRAME_GROOVE) gb_instances_label = FXVerticalFrame(gb_instances, FRAME_THICK) self.instlist = AFXList(gb_instances_label, 10, None, 0, LIST_BROWSESELECT | HSCROLLING_OFF) for instance in self.odb.rootAssembly.instances.keys(): self.instlist.appendItem(instance) gb_frames = FXGroupBox(hf_selectors, "Frame", FRAME_GROOVE) gb_frames_labels = FXVerticalFrame(gb_frames, FRAME_THICK) self.framelist = AFXList(gb_frames_labels, 10, None, 0, LIST_BROWSESELECT | HSCROLLING_OFF) for step in currentViewport.odbDisplay.fieldSteps: step_name = step[0] frames = step[7] for i, f in enumerate(frames): self.framelist.appendItem("%s: %d (%s)" % (step_name, i, f)) gb_variables = FXGroupBox(hf_selectors, "Variables", FRAME_GROOVE) gb_variables_label = FXVerticalFrame(gb_variables, FRAME_THICK) self.varlist = AFXList( gb_variables_label, 10, None, 0, LIST_BROWSESELECT | HSCROLLING_OFF | LIST_MULTIPLESELECT, ) for i, var in enumerate(self.variables): self.varlist.appendItem(var, None, i) hf_file = FXHorizontalFrame(self) self.sourceTextField = AFXTextField(hf_file, 20, "Export to:") self.sourceButton = FXButton(hf_file, "Select File", None, self, self.ID_CLICKED_FILE_BUTTON) self.check_deform = FXCheckButton(self, "Export deformed geometry.") self.check_deform.setCheck(state=True) self.appendActionButton("Export", self, self.ID_CLICKED_APPLY) self.appendActionButton(self.DISMISS) FXMAPFUNC(self, SEL_COMMAND, self.ID_CLICKED_APPLY, ExportODB.export) FXMAPFUNC(self, SEL_COMMAND, self.ID_CLICKED_FILE_BUTTON, ExportODB.select_file) def select_file(self, sender, sel, ptr): """Create file dialog, when the coresponding button was hit.""" # A pattern describes wich file types should be selected. patterns = ("VTK (*.vtk)\n" "VTK (*.vtu)\n" "STL (*.stl)\n" "Dolfin-XML (*.xml)\n" "Med (*.med)\n" "Medit (*.mesh)\n" "Gmsh4-binary (*.msh)\n" "Permas (*.post)\n" "Permas (*.post.gz)\n" "Permas (*.dato)\n" "Permas (*.dato.gz)\n" "Moab (*.h5m)\n" "Off (*.off)\n" "Xdmf (*.xdmf)\n" "Xmf (*.xmf)\n" "Mdpa (*.mdpa)\n" "SVG (*.svg)\n" "Patran (*.pat)\n" "Exodus (*.e)\n" "Exodus (*.ex2)\n" "Exodus (*.exo)\n" "All Files (*.*)") # open a file dialog and set it's target self.fileDialog = AFXFileSelectorDialog( self, "Select Source File", self.file_name, None, AFXSELECTFILE_ANY, patterns, ) self.fileDialog.create() self.fileDialog.show() return 1 def processUpdates(self): """Update fields. This is triggered by UI after each update. """ self.sourceTextField.setText(self.file_name.getValue()) def export(self, sender, sel, ptr): """Process inputs.""" instance_item = self.instlist.getSingleSelection() inst = self.instlist.getItemText(instance_item) frame_item = self.framelist.getSingleSelection() substring = self.framelist.getItemText(frame_item).split("(")[0] step, frame = substring.split(": ") deformed = bool(self.check_deform.getCheck()) variables = [] for i, var in enumerate(self.variables): if self.varlist.isItemSelected(i): variables.append(var) tgt = r"".join(self.file_name.getValue()) sendCommand("import meshio") sendCommand("from abq_meshio.abq_meshio_converter " "import convertODBtoMeshio") sendCommand("odb = session.openOdb('%s')" % self.odbFileNameFull) sendCommand("instance = odb.rootAssembly.instances['%s']" % inst) sendCommand("frame = odb.steps['%s'].frames[%d]" % (step, int(frame))) sendCommand("odb_mesh = convertODBtoMeshio(instance, frame," " list_of_outputs=['%s'], deformed=%s)" % ("','".join(variables), str(deformed))) sendCommand("meshio.write('%s', odb_mesh, write_binary=False)" % tgt) self.form.deactivate() return 1
class ExportMDB(AFXDataDialog): """Export MDB with meshio.""" [ID_CLICKED_FILE_BUTTON] = range(AFXDataDialog.ID_LAST, AFXDataDialog.ID_LAST + 1) def __init__(self, form): """Set up the initial dialog and connect Buttons to actions.""" self.form = form self.file_name = AFXStringTarget() AFXDataDialog.__init__(self, form, "Export MDB", 0, DIALOG_ACTIONS_SEPARATOR) FXLabel( self, "This plugin exports the current part or assembly with meshio.") hf_file = FXHorizontalFrame(self) self.sourceTextField = AFXTextField(hf_file, 20, "Export to:") self.sourceButton = FXButton(hf_file, "Select File", None, self, self.ID_CLICKED_FILE_BUTTON) self.appendActionButton("Export", self, self.ID_CLICKED_APPLY) self.appendActionButton(self.DISMISS) FXMAPFUNC(self, SEL_COMMAND, self.ID_CLICKED_APPLY, ExportMDB.export) FXMAPFUNC(self, SEL_COMMAND, self.ID_CLICKED_FILE_BUTTON, ExportMDB.select_file) def select_file(self, sender, sel, ptr): """Create file dialog, when the coresponding button was hit.""" # A pattern describes wich file types should be selected. patterns = ("VTK (*.vtk)\n" "VTK (*.vtu)\n" "STL (*.stl)\n" "Dolfin-XML (*.xml)\n" "Med (*.med)\n" "Medit (*.mesh)\n" "Gmsh4-binary (*.msh)\n" "Permas (*.post)\n" "Permas (*.post.gz)\n" "Permas (*.dato)\n" "Permas (*.dato.gz)\n" "Moab (*.h5m)\n" "Off (*.off)\n" "Xdmf (*.xdmf)\n" "Xmf (*.xmf)\n" "Mdpa (*.mdpa)\n" "SVG (*.svg)\n" "Patran (*.pat)\n" "Exodus (*.e)\n" "Exodus (*.ex2)\n" "Exodus (*.exo)\n" "All Files (*.*)") # open a file dialog and set it's target self.fileDialog = AFXFileSelectorDialog( self, "Select Source File", self.file_name, None, AFXSELECTFILE_ANY, patterns, ) self.fileDialog.create() self.fileDialog.show() return 1 def processUpdates(self): """Update fields. This is triggered by UI after each update. """ self.sourceTextField.setText(self.file_name.getValue()) def export(self, sender, sel, ptr): """Process inputs.""" tgt = r"".join(self.file_name.getValue()) if "." not in tgt: # Probably, the user left out a ending. Let's add ".vtk" tgt = tgt + ".vtk" sendCommand("import meshio") sendCommand( "from abq_meshio.abq_meshio_converter import convertMDBtoMeshio") sendCommand( "currentViewport = session.viewports[session.currentViewportName]") sendCommand("displayedObject = currentViewport.displayedObject") sendCommand("mdb_mesh = convertMDBtoMeshio(displayedObject)") sendCommand("print(mdb_mesh)") sendCommand("meshio.write('%s', mdb_mesh, binary=False)" % tgt) self.form.deactivate() return 1