Ejemplo n.º 1
0
    def copy_region(self):
        'copy the currently selected region'
        rows = self.tablewidget_regions.current_rows()

        if rows:
            data = self.tablewidget_regions.value

            for row in rows:
                name = list(data.keys())[row]
                new_region = deepcopy_dict(data[name], qobjects=True)

                new_name = get_unique_string(name, list(data.keys()))
                # update parameters before the new region is added to the dictionary
                self.update_parameter_name(None, new_name, new_region)
                data[new_name] = new_region
                data[new_name]['visible'] = self.get_visibility_image(
                    data[new_name]['visibility'])
                self.vtkwidget.new_region(new_name, data[new_name])

            self.tablewidget_regions.set_value(data)
            #self.tablewidget_regions.fit_to_contents()
            self.fixup_regions_table(self.tablewidget_regions)
            self.tablewidget_regions.selectRow(len(data) - 1)
            self.parent.set_unsaved_flag()
            self.parent.update_nav_tree()
Ejemplo n.º 2
0
    def create_parameter(self):
        btn = QtWidgets.QMessageBox.Yes
        if isinstance(self.value, Equation):
            message_box = QtWidgets.QMessageBox(self)
            message_box.setWindowTitle('Warning')
            message_box.setIcon(QtWidgets.QMessageBox.Warning)

            # Text
            message_box.setText("Warning: Replace equation with parameter?")

            message_box.addButton(QtWidgets.QMessageBox.Yes)
            message_box.addButton(QtWidgets.QMessageBox.No)
            message_box.setDefaultButton(QtWidgets.QMessageBox.No)
            btn = message_box.exec_()

        if btn == QtWidgets.QMessageBox.Yes:
            name = get_unique_string('param', PARAMETER_DICT.keys())

            v = self.dtype(0)
            if self.value:
                v = self.dtype(self.value)
            PARAMETER_DICT[name] = v

            self.updateValue(None, name)
            self.emitUpdatedValue()
Ejemplo n.º 3
0
 def create_vtk_widget(self, load):
     """ convert existing "New" tab to VTK tab """
     clear_layout(self.layout())
     name = get_unique_string('VTK', self.graphic_tabs.plot_dict.keys())
     self._change_name(name)
     from mfixgui.widgets.vtk_results_widget import GraphicsVtkWidget
     self.vtk_widget = GraphicsVtkWidget(self, load=load)
     self.layout().addWidget(self.vtk_widget)
     self.vtk = True
     return self.vtk_widget
Ejemplo n.º 4
0
    def new_parameter(self):
        data = self.parameters_dict
        new_name = get_unique_string('new', data.keys())

        i = data[new_name] = {
            'parameter': new_name,
            'type': 'float',
            'value': 0.0
        }

        i = self.add_item(i)
        self.tree.setCurrentItem(i)
        self.user_parent.setExpanded(True)
Ejemplo n.º 5
0
    def copy_parameter(self):
        items = self.tree.selectedItems()

        if items:
            data = self.parameters_dict
            for item in items:
                name = str(item.text(0))

                new_name = get_unique_string(name, data.keys())

                i = data[new_name] = {
                    'parameter': new_name,
                    'type': copy.deepcopy(data[name]['type']),
                    'value': copy.deepcopy(data[name]['value'])
                }
                i = self.add_item(i)
                self.tree.setCurrentItem(i)
Ejemplo n.º 6
0
    def check_name(self, name, old_name):
        """check the parameter name"""
        param_names = list(self.parameters_dict.keys())
        param_names.remove(old_name)

        if name in PROTECTED_NAMES or name in self.parent().keyword_doc:
            self.parent().message(
                title='Error',
                text=
                'The parameter name: <b>{}</b> is protected and cannot be used.'
                .format(name))
            return old_name
        elif name[0].isdigit():
            self.parent().message(
                title='Error',
                text='The parameter name: <b>{}</b> can not start with a digit.'
                .format(name))
            return old_name
        elif name in param_names:
            return get_unique_string(name, param_names)
        else:
            return name
Ejemplo n.º 7
0
    def new_region(self,
                   name=None,
                   extents=None,
                   rtype=None,
                   defer_update=False):
        """create a new region"""
        # This is used both as a signal callback and an API function,
        # so there's some complexity with default args/
        if name in (None, True, False):  # 'clicked' signal arguments
            name = 'R_1'  # shorter than 'region', better than 'new'
        # Would be nice to name a box 'box', plane 'plane', etc but
        #  they all start as 'box' and then are changed to new type

        data = self.tablewidget_regions.value
        name = get_unique_string(name, list(data.keys()))

        reg_dat = deepcopy_dict(DEFAULT_REGION_DATA, qobjects=True)
        if rtype is not None and extents is not None:
            reg_dat['type'] = rtype
            reg_dat['from'] = extents[0]
            reg_dat['to'] = extents[1]
        reg_dat['visible'] = self.get_visibility_image(True)
        reg_dat['color'].rand()

        # update parameters before the new region is added to the dictionary
        self.update_parameter_name(None, name, reg_dat)

        data[name] = reg_dat
        self.tablewidget_regions.set_value(data)
        self.vtkwidget.new_region(name, reg_dat)
        if defer_update:
            return

        #self.tablewidget_regions.fit_to_contents()
        self.fixup_regions_table(self.tablewidget_regions)
        self.tablewidget_regions.selectRow(len(data) - 1)  # Select new row
        self.parent.set_unsaved_flag()
        self.parent.update_nav_tree()  # Enable/disable ICs/BCs etc
Ejemplo n.º 8
0
    def region_value_changed(self,
                             widget,
                             value,
                             args,
                             name=None,
                             update_param=True):
        'one of the region widgets values changed, update'
        rows = self.tablewidget_regions.current_rows()
        data = self.tablewidget_regions.value
        if name is None:
            name = list(data.keys())[rows[-1]]
        elif name not in data:
            self.error("region %s not defined" % name)
            return
        key = list(value.keys())[0]
        row_data = data[name]

        self.parent.set_unsaved_flag()

        shape = row_data['type']
        to = 'to' in key
        from_ = 'from' in key
        stl = self.checkbox_selectfacets.isChecked()
        if to or from_:
            item = key.split('_')
            axis = item[1]
            index = ['x', 'y', 'z'].index(axis)
            val = list(value.values())[0]

            # check for equation and special parameters max, min
            if isinstance(val, Equation):
                used = val.get_used_parameters()
                if 'min' in used or 'max' in used:
                    val.eq = val.eq.replace('min', axis + 'min').replace(
                        'max', axis + 'max')
                    widget.updateValue(None, val)
            if update_param:
                self.update_parameter_map(value[key], name, key)

            # update data dict
            row_data[item[0]][index] = val

            users = self.parent.get_region_users(name)
            # Infer shape from extents
            if not users:
                old_shape = row_data.get('type', 'box')
                if stl:
                    shape = 'STL'
                else:
                    shape = row_data['type'] = self.get_region_type(
                        [row_data['from'], row_data['to']])
                if old_shape != shape:
                    self.vtkwidget.change_region_type(name, row_data)

            # check for and update point and plane extents
            shape = data[name]['type']
            if users and any(s in shape
                             for s in ['plane', 'point'
                                       ]) and item[1] not in shape.lower():
                self.update_parameter_map(val, name, 'to_' + str(item[1]))
                row_data['to'][index] = val
                self.extent_lineedits[index * 2 + 1].updateValue(None, val)

            # propagate values
            for update in (self.vtkwidget.update_region,
                           self.parent.update_region):
                update(name, row_data)

        elif 'name' in key and name != list(value.values())[0]:
            new_name = get_unique_string(
                list(value.values())[0], list(data.keys()))

            if new_name:
                self.parent.change_region_name(name, new_name)
            else:
                self.parent.error('invalid value %s' % value)
                return

            data = OrderedDict(((new_name, v) if k == name else (k, v)
                                for (k, v) in data.items()))

            self.vtkwidget.change_region_name(name, new_name)
            # TODO FIXME fit table to contents

            # update parameter map
            self.update_parameter_name(name, new_name, row_data)

        elif 'type' in key:
            shape = list(value.values())[0]
            if shape is None:
                shape = self.get_region_type(
                    [row_data['from'], row_data['to']])
            data[name]['type'] = shape
            self.vtkwidget.change_region_type(name, data[name])
            self.enable_disable_widgets(name)

            # check for plane, update extents
            if 'plane' in shape:
                shape = shape.lower()
                index = [d not in shape for d in 'xyz'].index(True)
                f_value = data[name]['from'][index]
                self.update_parameter_map(f_value, name, 'to_' + 'xyz'[index])
                row_data['to'][index] = f_value
                self.extent_lineedits[index * 2 + 1].updateValue(None, f_value)
            # check for point, update extents
            elif shape == 'point':
                for index in (0, 1, 2):
                    f_value = row_data['from'][index]
                    row_data['to'][index] = f_value
                    self.update_parameter_map(f_value, name,
                                              'to_' + 'xyz'[index])
                    self.extent_lineedits[index * 2 + 1].updateValue(
                        None, f_value)

        #TODO this seems like lots of copy/paste
        elif 'stl_shape' in key:
            row_data['stl_shape'] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

        elif 'slice' in key:
            row_data['slice'] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

        elif 'filter_facets' in key:
            row_data['filter_facets'] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

        elif 'equilibrant' in key:
            row_data['equilibrant'] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

        elif 'invert' in key:
            row_data['invert'] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

        elif 'filter' in key:
            item = key.split('_')
            index = ['x', 'y', 'z'].index(item[1])
            row_data[item[0]][index] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

            if update_param:
                self.update_parameter_map(value[key], name, key)

        elif 'deviation_angle' in key:
            row_data['deviation_angle'] = list(value.values())[0]
            self.vtkwidget.update_region(name, row_data)

            if update_param:
                self.update_parameter_map(value[key], name, key)

        self.tablewidget_regions.set_value(data)

        if key == 'type':
            self.parent.update_nav_tree(
            )  # ICs/BCs availability depends on region types
Ejemplo n.º 9
0
    def apply_(self):

        v = {}
        for widget in widget_iter(self.ui):
            name = str(widget.objectName()).split('_')
            if 'lineedit' in name:
                v[name[1]] = widget.value

        # create bed
        b = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        b['radius'] = v['db'] / 2.0
        b['height'] = v['hb']
        b['type'] = 'cylinder'
        b['resolution'] = 30
        b_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'bed', self.vtk_widget.geometrydict.keys()),
                                               data=b)

        # create cone
        c = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        c['radius'] = v['df'] / 2.0
        cone_angle = math.atan(v['hc'] / (v['df'] / 2.0 - v['db'] / 2.0))
        add_h = v['db'] / 2.0 * math.tan(cone_angle)
        c['height'] = v['hc'] + add_h
        c['type'] = 'cone'
        c['resolution'] = 30
        c['rotationz'] = -90
        c['centery'] = v['hb'] / 2.0 + v['hc'] / 2.0 - add_h / 2.0
        c_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'cone', self.vtk_widget.geometrydict.keys()),
                                               data=c)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[b_name, c_name])

        # create freeboard
        f = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        f['radius'] = v['df'] / 2.0
        f['height'] = v['hf']
        f['type'] = 'cylinder'
        f['resolution'] = 30
        f['centery'] = v['hb'] / 2.0 + v['hc'] + v['hf'] / 2.0
        f_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'freeboard', self.vtk_widget.geometrydict.keys()),
                                               data=f)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[f_name, union])

        # create top outlet
        if self.ui.groupbox_to.isChecked():
            to = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
            to['radius'] = v['dto'] / 2.0
            to['height'] = v['hto'] * 2
            to['type'] = 'cylinder'
            to['resolution'] = 20
            to['centery'] = v['hb'] / 2.0 + v['hc'] + v['hf']
            to_name = self.vtk_widget.add_primitive(name=get_unique_string(
                'top_outlet', self.vtk_widget.geometrydict.keys()),
                                                    data=to)

            union = self.vtk_widget.boolean_operation(
                booltype='union', children=[to_name, union])

        # create side outlet
        if self.ui.groupbox_so.isChecked():
            so = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
            so['radius'] = v['dso'] / 2.0
            so['height'] = v['hso'] * 2
            so['type'] = 'cylinder'
            so['resolution'] = 20
            so['centery'] = v['hb'] / 2.0 + v['hc'] + v['hf'] - v['eso']
            so['centerx'] = v['df'] / 2.0
            so['rotationz'] = -90
            so_name = self.vtk_widget.add_primitive(name=get_unique_string(
                'top_outlet', self.vtk_widget.geometrydict.keys()),
                                                    data=so)

            union = self.vtk_widget.boolean_operation(
                booltype='union', children=[so_name, union])

        # create spout
        if self.ui.groupbox_spouted.isChecked():
            # create cone
            c = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
            c['radius'] = v['db'] / 2.0
            tan = math.tan(math.radians(v['as']))
            height = v['db'] / 2.0 * tan
            add_h = v['ds'] / 2.0 * tan
            c['height'] = height + add_h
            c['type'] = 'cone'
            c['resolution'] = 30
            c['rotationz'] = -90
            c['centery'] = -v['hb'] / 2.0 - height / 2.0 - add_h / 2.0
            c_name = self.vtk_widget.add_primitive(name=get_unique_string(
                'spout', self.vtk_widget.geometrydict.keys()),
                                                   data=c)

            union = self.vtk_widget.boolean_operation(booltype='union',
                                                      children=[union, c_name])

            s = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
            s['radius'] = v['ds'] / 2.0
            s['height'] = v['ds'] * 2
            s['type'] = 'cylinder'
            s['resolution'] = 20
            s['centery'] = -v['hb'] / 2.0 - height - v['ds'] + add_h / 2.0
            s_name = self.vtk_widget.add_primitive(name=get_unique_string(
                'top_outlet', self.vtk_widget.geometrydict.keys()),
                                                   data=s)

            union = self.vtk_widget.boolean_operation(booltype='union',
                                                      children=[s_name, union])

        self.close()
Ejemplo n.º 10
0
    def apply_(self):

        v = {}
        for widget in widget_iter(self.ui):
            name = str(widget.objectName()).split('_')
            if 'lineedit' in name:
                v[name[1]] = widget.value

        # create hopper
        h = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        h['radius'] = v['dh'] / 2.0
        h['height'] = v['hh']
        h['type'] = 'cylinder'
        h['resolution'] = 30
        h_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'hopper', self.vtk_widget.geometrydict.keys()),
                                               data=h)

        # create cone
        c = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        c['radius'] = v['dh'] / 2.0
        tan = math.tan(math.radians(v['ah']))
        height = v['dh'] / 2.0 * tan
        add_h = v['do'] / 2.0 * tan
        c['height'] = height + add_h
        c['type'] = 'cone'
        c['resolution'] = 30
        c['rotationz'] = -90
        c['centery'] = -v['hh'] / 2.0 - height / 2.0 - add_h / 2.0
        c_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'cone', self.vtk_widget.geometrydict.keys()),
                                               data=c)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[h_name, c_name])

        # outlet
        o = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        o['radius'] = v['do'] / 2.0
        o['height'] = v['ho']
        o['type'] = 'cylinder'
        o['resolution'] = 20
        o['centery'] = -v['hh'] / 2.0 - height - v['ho'] / 2.0 + add_h / 2.0
        o_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'outlet', self.vtk_widget.geometrydict.keys()),
                                               data=o)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[o_name, union])

        # outlet
        if self.ui.groupbox_collector.isChecked():
            c = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
            c['radius'] = v['dc'] / 2.0
            c['height'] = v['hc']
            c['type'] = 'cylinder'
            c['resolution'] = 20
            c['centery'] = -v['hh'] / 2.0 - height - v[
                'ho'] - v['hc'] / 2.0 + add_h / 2.0 + v['hc'] / 100.0
            c_name = self.vtk_widget.add_primitive(name=get_unique_string(
                'outlet', self.vtk_widget.geometrydict.keys()),
                                                   data=c)

            union = self.vtk_widget.boolean_operation(booltype='union',
                                                      children=[c_name, union])

        self.close()
Ejemplo n.º 11
0
 def add_tab(self, name="New"):
     """callback to add a new tab to tabWidgetGraphics"""
     name = get_unique_string(name, self.plot_dict.keys())
     self.set_unsaved_flag()
     return self.create_tab(name)
Ejemplo n.º 12
0
    def create_monitor_plot_widget(self, name='Monitors'):
        """ convert existing "New" tab to a monitor plot tab """
        layout = self.layout()

        clear_layout(layout)
        name = get_unique_string(name, self.graphic_tabs.plot_dict.keys())
        self._change_name(name)

        self.monitors = True
        self.curve = {}
        self.color_cycle = itertools.cycle(DEFAULT_PENS)

        mr = self.graphic_tabs.monitor_reader
        mr.connect(self.update_monitors)

        # splitter
        splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
        layout.addWidget(splitter, 0, 0)

        # plot widget
        plot = self.plot_widget = PlotWidget()
        plot.getPlotItem().showGrid(True, True, 0.5)
        plot.setDownsampling(ds=False, auto=True, mode='subsample')
        plot.setLabel('bottom', 'Time [s]')

        plot.addLegend()
        # monkey patch updateSize of the legend
        legend = plot.plotItem.legend
        legend.updateSize = lambda: legend_patch(legend)
        splitter.addWidget(plot)

        # table
        opt_widget = QtWidgets.QWidget(self)
        opt_layout = QtWidgets.QGridLayout(opt_widget)
        opt_layout.setContentsMargins(0, 0, 0, 0)

        # save
        tb_sv = QtWidgets.QToolButton()
        tb_sv.setToolTip('save plot')
        tb_sv.setIcon(get_icon('save.svg'))
        tb_sv.setAutoRaise(True)
        plot.sceneObj.contextMenuItem = plot.plotItem.vb  # fix missing attr
        tb_sv.clicked.connect(plot.sceneObj.showExportDialog)
        opt_layout.addWidget(tb_sv, 0, 0)

        # hide/show legend
        tb_lg = QtWidgets.QToolButton()
        tb_lg.setToolTip('hide/show legend')
        tb_lg.setCheckable(True)
        tb_lg.setChecked(True)
        tb_lg.setIcon(get_icon('bullet_list.svg'))
        tb_lg.setAutoRaise(True)
        tb_lg.clicked.connect(lambda: legend.setVisible(tb_lg.isChecked()))
        opt_layout.addWidget(tb_lg, 0, 1)

        mt = self.monitor_table = Table(
            dtype=dict,
            columns=['visible', 'color', 'variable', 'monitor'],
            selection_behavior='row',
            multi_selection=True)
        mt.set_value(dict())
        mt.show_vertical_header(False)
        mt.auto_update_rows(True)
        mt.clicked.connect(self.cell_clicked)
        mt.setEditTriggers(QtWidgets.QTableView.NoEditTriggers)

        # right click menu
        menu = QtWidgets.QMenu(mt)
        for text, method in [
            ('Select All', self.select_all),
            ('Clear Selection', self.clear_selection),
            ('Hide', self.hide_curves),
            ('Show', self.show_curves),
        ]:
            action = QtWidgets.QAction(text, mt)
            action.triggered.connect(method)
            menu.addAction(action)

        mt.menu = menu
        opt_layout.addWidget(mt, 1, 0, 1, 10)

        splitter.addWidget(opt_widget)
        splitter.setSizes([800, 200])

        # lb = QtWidgets.QLabel('X Axis')
        # layout.addWidget(lb, 2, 0)
        # cb = self.x_axis_cb = ComboBox()
        # cb.addItems(['Time'])
        # layout.addWidget(cb, 2, 1)

        for path in mr.data.keys():
            self.update_monitors(path, mr.data)
Ejemplo n.º 13
0
    def apply_(self):

        v = {}
        for widget in widget_iter(self.ui):
            name = str(widget.objectName()).split('_')
            if 'lineedit' in name:
                v[name[1]] = widget.value

        # create barrel
        b = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        b['radius'] = v['dc'] / 2.0
        b['height'] = v['c']
        b['type'] = 'cylinder'
        b['resolution'] = 30
        b_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'barrel', self.vtk_widget.geometrydict.keys()),
                                               data=b)

        # create cone
        c = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        c['radius'] = v['dc'] / 2.0
        cone_angle = math.atan(v['b'] / (v['dc'] / 2.0 - v['e'] / 2.0))
        add_h = v['e'] / 2.0 * math.tan(cone_angle)
        c['height'] = v['b'] + add_h
        c['type'] = 'cone'
        c['resolution'] = 30
        c['rotationz'] = -90
        c['centery'] = -v['c'] / 2.0 - v['b'] / 2.0 - add_h / 2.0
        c_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'cone', self.vtk_widget.geometrydict.keys()),
                                               data=c)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[b_name, c_name])

        # create solids outlet
        so = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        so['radius'] = v['e'] / 2.0
        so['height'] = v['e'] * 2
        so['type'] = 'cylinder'
        so['resolution'] = 30
        so['centery'] = -v['e'] - v['c'] / 2.0 - v['b']
        so_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'soilds', self.vtk_widget.geometrydict.keys()),
                                                data=so)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[union, so_name])

        # inlet
        i = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        i['lengthx'] = v['l']
        i['lengthy'] = v['k']
        i['lengthz'] = v['dc']
        i['centerx'] = v['l'] / 2.0 - v['dc'] / 2.0
        i['centery'] = -v['k'] / 2.0 + v['c'] / 2.0 - v['k'] / 500
        i['centerz'] = v['dc'] / 2.0
        i['type'] = 'box'
        i_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'inlet', self.vtk_widget.geometrydict.keys()),
                                               data=i)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[union, i_name])

        # clean
        union = self.vtk_widget.add_filter(
            'clean',
            name=get_unique_string('clean',
                                   self.vtk_widget.geometrydict.keys()),
            child=union)

        # fill holes
        union = self.vtk_widget.add_filter(
            'fill_holes',
            name=get_unique_string('fill_holes',
                                   self.vtk_widget.geometrydict.keys()),
            child=union)

        # vortex finder
        v_c = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        v_c['radius'] = v['m'] / 2.0 + v['n']
        v_c['height'] = v['f'] * 2
        v_c['type'] = 'cylinder'
        v_c['resolution'] = 30
        v_c['centery'] = v['c'] / 2.0
        v_c_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'vortex_cut', self.vtk_widget.geometrydict.keys()),
                                                 data=v_c)

        union = self.vtk_widget.boolean_operation(booltype='diff',
                                                  children=[union, v_c_name])

        # outlet
        o = copy.deepcopy(DEFAULT_PRIMITIVE_PARAMS)
        o['radius'] = v['m'] / 2.0
        o['height'] = v['f'] * 2 + v['f'] / 10.0
        o['type'] = 'cylinder'
        o['resolution'] = 30
        o['centery'] = v['c'] / 2.0 - v['f'] / 10.0
        o_name = self.vtk_widget.add_primitive(name=get_unique_string(
            'outlet', self.vtk_widget.geometrydict.keys()),
                                               data=o)

        union = self.vtk_widget.boolean_operation(booltype='union',
                                                  children=[union, o_name])

        self.close()