예제 #1
0
def buildSpiralPolyDataItem(drawOpts):
    xmin, xmax, ymin, ymax = drawOpts['vp']
    color = drawOpts['color']
    lineWidth = drawOpts['lineWidth']
    stippleType = drawOpts['stippleType']

    spiralPoints = [[0.1, 0.1], [0.1, 0.9], [0.9, 0.9], [0.9, 0.2], [0.2, 0.2],
                    [0.2, 0.8], [0.8, 0.8], [0.8, 0.3], [0.3, 0.3], [0.3, 0.7],
                    [0.7, 0.7], [0.7, 0.4], [0.4, 0.4], [0.4, 0.6], [0.6, 0.6],
                    [0.6, 0.5]]

    xformedPoints = [[
        affine(p[0], 0.0, 1.0, xmin, xmax),
        affine(p[1], 0.0, 1.0, ymin, ymax), 0.0
    ] for p in spiralPoints]

    pd = vtk.vtkPolyData()
    pd.Allocate(50)

    pts = vtk.vtkPoints()

    for pt in xformedPoints:
        pts.InsertNextPoint(pt)

    pd.SetPoints(pts)

    numpts = len(xformedPoints)
    pd.InsertNextCell(vtk.VTK_POLY_LINE, numpts,
                      [idx for idx in range(numpts)])

    colors = vtk.vtkUnsignedCharArray()
    colors.SetNumberOfComponents(4)
    colors.SetNumberOfTuples(1)

    colors.SetTuple4(0, color[0], color[1], color[2], 255)

    # Specify line width
    floatValue = vtk.vtkFloatArray()
    floatValue.SetNumberOfComponents(1)
    floatValue.SetName("LineWidth")
    floatValue.InsertNextValue(lineWidth)
    pd.GetFieldData().AddArray(floatValue)

    # Specify stipple pattern
    intValue = vtk.vtkIntArray()
    intValue.SetNumberOfComponents(1)
    intValue.SetName("StippleType")
    intValue.InsertNextValue(stippleType)
    pd.GetFieldData().AddArray(intValue)

    item = vtk.vtkPolyDataItem()
    item.SetPolyData(pd)
    item.SetMappedColors(colors)
    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
    item.SetVisible(True)

    return item
예제 #2
0
    def _plotInternal(self):
        """Overrides baseclass implementation."""
        # Special case for custom boxfills:
        if self._gm.boxfill_type != "custom":
            self._plotInternalBoxfill()
        else:
            self._plotInternalCustomBoxfill()

        if self._maskedDataMapper is not None:
            self._mappers.insert(0, self._maskedDataMapper)

        plotting_dataset_bounds = self.getPlottingBounds()
        x1, x2, y1, y2 = plotting_dataset_bounds

        if self._vtkGeoTransform:
            x1 = self._vtkDataSetBoundsNoMask[0]
            x2 = self._vtkDataSetBoundsNoMask[1]
            y1 = self._vtkDataSetBoundsNoMask[2]
            y2 = self._vtkDataSetBoundsNoMask[3]
            drawAreaBounds = vcs2vtk.computeDrawAreaBounds([x1, x2, y1, y2],
                                                           self._context_flipX,
                                                           self._context_flipY)
        else:
            drawAreaBounds = vcs2vtk.computeDrawAreaBounds([x1, x2, y1, y2])

        # And now we need actors to actually render this thing
        actors = []
        cti = 0
        ctj = 0
        _colorMap = self.getColorMap()
        _style = self._gm.fillareastyle
        vp = self._resultDict.get('ratio_autot_viewport', [
            self._template.data.x1, self._template.data.x2,
            self._template.data.y1, self._template.data.y2
        ])

        fareapixelspacing, fareapixelscale = self._patternSpacingAndScale()

        # view and interactive area
        view = self._context().contextView
        area = vtk.vtkInteractiveArea()
        view.GetScene().AddItem(area)

        [renWinWidth, renWinHeight] = self._context().renWin.GetSize()
        # vp = vcs2vtk.adjustBounds(vp, 0.9, 0.9)
        geom = vtk.vtkRecti(int(round(vp[0] * renWinWidth)),
                            int(round(vp[2] * renWinHeight)),
                            int(round((vp[1] - vp[0]) * renWinWidth)),
                            int(round((vp[3] - vp[2]) * renWinHeight)))

        vcs2vtk.configureContextArea(area, drawAreaBounds, geom)

        midx = 0

        for mapper in self._mappers:
            act = vtk.vtkActor()
            act.SetMapper(mapper)
            mapper.Update()
            poly = mapper.GetInput()

            if _style == "solid":
                if self._needsCellData:
                    attrs = poly.GetCellData()
                else:
                    attrs = poly.GetPointData()

                data = attrs.GetScalars()
                deleteColors = False

                if data:
                    lut = mapper.GetLookupTable()
                    range = mapper.GetScalarRange()
                    lut.SetRange(range)
                    mappedColors = lut.MapScalars(data,
                                                  vtk.VTK_COLOR_MODE_DEFAULT,
                                                  0)
                    deleteColors = True
                else:
                    loc = 'point'
                    numTuples = poly.GetNumberOfPoints()
                    if self._needsCellData:
                        loc = 'cell'
                        numTuples = poly.GetNumberOfCells()
                    msg = 'WARNING: boxfill pipeline: poly does not have Scalars'
                    msg = msg + 'array on {0} data, using solid color'.format(
                        loc)
                    print(msg)
                    color = [0, 0, 0, 255]
                    mappedColors = vcs2vtk.generateSolidColorArray(
                        numTuples, color)

                mappedColors.SetName('Colors')

                item = vtk.vtkPolyDataItem()
                item.SetPolyData(poly)

                if self._needsCellData:
                    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
                else:
                    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_POINT_DATA)

                item.SetMappedColors(mappedColors)
                if deleteColors:
                    mappedColors.FastDelete()
                area.GetDrawAreaItem().AddItem(item)

                if mapper is self._maskedDataMapper:
                    actors.append([
                        item, self._maskedDataMapper, plotting_dataset_bounds
                    ])
                else:
                    actors.append([item, plotting_dataset_bounds])

            if mapper is not self._maskedDataMapper:
                if self._gm.boxfill_type == "custom":
                    # Patterns/hatches creation for custom boxfill plots
                    patact = None

                    tmpColors = self._customBoxfillArgs["tmpColors"]
                    if ctj >= len(tmpColors[cti]):
                        ctj = 0
                        cti += 1
                    # Since pattern creation requires a single color, assuming the first
                    c = self.getColorIndexOrRGBA(_colorMap,
                                                 tmpColors[cti][ctj])

                    patact = fillareautils.make_patterned_polydata(
                        poly,
                        fillareastyle=_style,
                        fillareaindex=self._customBoxfillArgs["tmpIndices"]
                        [cti],
                        fillareacolors=c,
                        fillareaopacity=self._customBoxfillArgs["tmpOpacities"]
                        [cti],
                        fillareapixelspacing=fareapixelspacing,
                        fillareapixelscale=fareapixelscale,
                        size=self._context().renWin.GetSize(),
                        screenGeom=self._context().renWin.GetSize())

                    ctj += 1

                    if patact is not None:
                        patMapper = patact.GetMapper()
                        patMapper.Update()
                        patPoly = patMapper.GetInput()

                        patItem = vtk.vtkPolyDataItem()
                        patItem.SetPolyData(patPoly)

                        patItem.SetScalarMode(
                            vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
                        colorArray = patPoly.GetCellData().GetArray('Colors')

                        patItem.SetMappedColors(colorArray)
                        area.GetDrawAreaItem().AddItem(patItem)

                        actors.append([patItem, plotting_dataset_bounds])

            midx += 1

        self._resultDict["vtk_backend_actors"] = actors

        z, t = self.getZandT()

        kwargs = {
            "vtk_backend_grid":
            self._vtkDataSet,
            "dataset_bounds":
            self._vtkDataSetBounds,
            "plotting_dataset_bounds":
            plotting_dataset_bounds,
            "vtk_dataset_bounds_no_mask":
            self._vtkDataSetBoundsNoMask,
            "vtk_backend_geo":
            self._vtkGeoTransform,
            "vtk_backend_draw_area_bounds":
            drawAreaBounds,
            "vtk_backend_viewport_scale":
            [self._context_xScale, self._context_yScale]
        }
        if ("ratio_autot_viewport" in self._resultDict):
            kwargs["ratio_autot_viewport"] = vp
        self._resultDict.update(self._context().renderTemplate(
            self._template, self._data1, self._gm, t, z, **kwargs))

        if getattr(self._gm, "legend", None) is not None:
            self._contourLabels = self._gm.legend

        if self._gm.ext_1:
            if isinstance(self._contourLevels[0], list):
                if numpy.less(abs(self._contourLevels[0][0]), 1.e20):
                    # Ok we need to add the ext levels
                    self._contourLevels.insert(
                        0, [-1.e20, self._contourLevels[0][0]])
            else:
                if numpy.less(abs(self._contourLevels[0]), 1.e20):
                    # need to add an ext
                    self._contourLevels.insert(0, -1.e20)
        if self._gm.ext_2:
            if isinstance(self._contourLevels[-1], list):
                if numpy.less(abs(self._contourLevels[-1][1]), 1.e20):
                    # need ext
                    self._contourLevels.append(
                        [self._contourLevels[-1][1], 1.e20])
            else:
                if numpy.less(abs(self._contourLevels[-1]), 1.e20):
                    # need exts
                    self._contourLevels.append(1.e20)

        # Do not pass patterning parameters for color bar rendering if the
        # boxfill type is non-custom
        patternArgs = {}
        if self._gm.boxfill_type == "custom":
            patternArgs['style'] = self._gm.fillareastyle
            patternArgs['index'] = self._gm.fillareaindices
            patternArgs['opacity'] = self._gm.fillareaopacity
            # Compensate for the different viewport size of the colorbar
            patternArgs['pixelspacing'] = [
                int(fareapixelspacing[0] / (vp[1] - vp[0])),
                int(fareapixelspacing[1] / (vp[3] - vp[2]))
            ]
            patternArgs['pixelscale'] = fareapixelscale / (vp[1] - vp[0])

        self._resultDict.update(self._context().renderColorBar(
            self._template, self._contourLevels, self._contourColors,
            self._contourLabels, self.getColorMap(), **patternArgs))

        projection = vcs.elements["projection"][self._gm.projection]
        kwargs['xaxisconvert'] = self._gm.xaxisconvert
        kwargs['yaxisconvert'] = self._gm.yaxisconvert
        if self._data1.getAxis(-1).isLongitude() and self._data1.getAxis(
                -2).isLatitude():
            self._context().plotContinents(
                self._plot_kargs.get("continents", self._useContinents),
                plotting_dataset_bounds, projection, self._dataWrapModulo, vp,
                self._template.data.priority, **kwargs)
예제 #3
0
area = vtk.vtkInteractiveArea()
view.GetScene().AddItem(area)

drawAreaBounds = vtk.vtkRectd(0.0, 0.0, 1.0, 1.0)

vp = [0.0500000007451, 0.949999988079, 0.259999990463, 0.860000014305]
screenGeometry = vtk.vtkRecti(int(vp[0] * width), int(vp[2] * height),
                              int((vp[1] - vp[0]) * width),
                              int((vp[3] - vp[2]) * height))

for obj in polyDataList:
    pd = obj['poly']
    col = obj['color']

    item = vtk.vtkPolyDataItem()
    item.SetPolyData(pd)
    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
    mappedColors = vtk.vtkUnsignedCharArray()
    mappedColors.SetNumberOfComponents(4)
    mappedColors.SetNumberOfTuples(pd.GetNumberOfCells())

    for i in range(pd.GetNumberOfCells()):
        mappedColors.SetTuple4(i, *col)

    item.SetMappedColors(mappedColors)
    item.SetVisible(True)
    area.GetDrawAreaItem().AddItem(item)

lastItem = vtk.vtkPolyDataItem()
pd, colors = buildPolyDataItemMixed()
def buildSpiralPolyDataItem(drawOpts):
    xmin, xmax, ymin, ymax = drawOpts['vp']
    color = drawOpts['color']
    lineWidth = drawOpts['lineWidth']
    stippleType = drawOpts['stippleType']

    spiralPoints = [
        [0.1, 0.1],
        [0.1, 0.9],
        [0.9, 0.9],
        [0.9, 0.2],

        [0.2, 0.2],
        [0.2, 0.8],
        [0.8, 0.8],
        [0.8, 0.3],

        [0.3, 0.3],
        [0.3, 0.7],
        [0.7, 0.7],
        [0.7, 0.4],

        [0.4, 0.4],
        [0.4, 0.6],
        [0.6, 0.6],
        [0.6, 0.5]
    ]

    xformedPoints = [[
        affine(p[0], 0.0, 1.0, xmin, xmax),
        affine(p[1], 0.0, 1.0, ymin, ymax),
        0.0
    ] for p in spiralPoints]

    pd = vtk.vtkPolyData()
    pd.Allocate(50)

    pts = vtk.vtkPoints()

    for pt in xformedPoints:
        pts.InsertNextPoint(pt)

    pd.SetPoints(pts)

    numpts = len(xformedPoints)
    pd.InsertNextCell(vtk.VTK_POLY_LINE, numpts, [idx for idx in range(numpts)])

    colors = vtk.vtkUnsignedCharArray()
    colors.SetNumberOfComponents(4)
    colors.SetNumberOfTuples(1)

    colors.SetTuple4(0, color[0], color[1], color[2], 255)

    # Specify line width
    floatValue = vtk.vtkFloatArray()
    floatValue.SetNumberOfComponents(1)
    floatValue.SetName("LineWidth")
    floatValue.InsertNextValue(lineWidth)
    pd.GetFieldData().AddArray(floatValue)

    # Specify stipple pattern
    intValue = vtk.vtkIntArray()
    intValue.SetNumberOfComponents(1)
    intValue.SetName("StippleType")
    intValue.InsertNextValue(stippleType)
    pd.GetFieldData().AddArray(intValue)

    item = vtk.vtkPolyDataItem()
    item.SetPolyData(pd)
    item.SetMappedColors(colors)
    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
    item.SetVisible(True)

    return item
예제 #5
0
    def _plotInternal(self):

        prepedContours = self._prepContours()
        tmpLevels = prepedContours["tmpLevels"]
        tmpIndices = prepedContours["tmpIndices"]
        tmpColors = prepedContours["tmpColors"]
        tmpOpacities = prepedContours["tmpOpacities"]

        style = self._gm.fillareastyle
        fareapixelspacing, fareapixelscale = self._patternSpacingAndScale()

        mappers = []
        luts = []
        geos = []
        wholeDataMin, wholeDataMax = vcs.minmax(self._data1)
        plotting_dataset_bounds = self.getPlottingBounds()
        x1, x2, y1, y2 = plotting_dataset_bounds
        # We need to do the convertion thing
        _convert = self._gm.yaxisconvert
        _func = vcs.utils.axisConvertFunctions[_convert]["forward"]
        y1 = _func(y1)
        y2 = _func(y2)
        _convert = self._gm.xaxisconvert
        _func = vcs.utils.axisConvertFunctions[_convert]["forward"]
        x1 = _func(x1)
        x2 = _func(x2)
        _colorMap = self.getColorMap()
        for i, l in enumerate(tmpLevels):
            # Ok here we are trying to group together levels can be, a join
            # will happen if: next set of levels contnues where one left off
            # AND pattern is identical
            # TODO this should really just be a single polydata that is
            # colored by scalars:
            for j, color in enumerate(tmpColors[i]):
                mapper = vtk.vtkPolyDataMapper()
                lut = vtk.vtkLookupTable()
                th = vtk.vtkThreshold()
                th.ThresholdBetween(l[j], l[j + 1])
                # th.SetInputConnection(self._vtkPolyDataFilter.GetOutputPort())
                th.SetInputData(self._vtkDataSetFittedToViewport)
                geoFilter2 = vtk.vtkDataSetSurfaceFilter()
                geoFilter2.SetInputConnection(th.GetOutputPort())
                # Make the polydata output available here for patterning later
                geoFilter2.Update()
                geos.append(geoFilter2)
                mapper.SetInputConnection(geoFilter2.GetOutputPort())
                lut.SetNumberOfTableValues(1)
                r, g, b, a = self.getColorIndexOrRGBA(_colorMap, color)
                if style == 'solid':
                    tmpOpacity = tmpOpacities[j]
                    if tmpOpacity is None:
                        tmpOpacity = a / 100.
                    else:
                        tmpOpacity = tmpOpacities[j] / 100.
                    lut.SetTableValue(0, r / 100., g / 100., b / 100.,
                                      tmpOpacity)
                else:
                    lut.SetTableValue(0, 1., 1., 1., 0.)
                mapper.SetLookupTable(lut)
                mapper.SetScalarRange(l[j], l[j + 1])
                luts.append([lut, [l[j], l[j + 1], True]])
                # Store the mapper only if it's worth it?
                # Need to do it with the whole slab min/max for animation
                # purposes
                if not (l[j + 1] < wholeDataMin or l[j] > wholeDataMax):
                    mappers.append(mapper)

        self._resultDict["vtk_backend_luts"] = luts
        if len(geos) > 0:
            self._resultDict["vtk_backend_geofilters"] = geos

        if self._maskedDataMapper is not None:
            # Note that this is different for meshfill -- others prepend.
            mappers.append(self._maskedDataMapper)

        wireColor = [0, 0, 0, 255]

        # Add a second mapper for wireframe meshfill:
        if self._gm.mesh:
            lineMappers = []
            for polyMapper in mappers:
                edgeFilter = vtk.vtkExtractEdges()
                edgeFilter.SetInputConnection(
                    polyMapper.GetInputConnection(0, 0))

                lineMapper = vtk.vtkPolyDataMapper()
                lineMapper.SetInputConnection(edgeFilter.GetOutputPort(0))

                lineMapper._useWireFrame = True

                lineMappers.append(lineMapper)
            mappers.extend(lineMappers)

        # And now we need actors to actually render this thing
        actors = []
        vp = self._resultDict.get('ratio_autot_viewport', [
            self._template.data.x1, self._template.data.x2,
            self._template.data.y1, self._template.data.y2
        ])
        cti = 0
        ctj = 0

        # view and interactive area
        view = self._context().contextView
        area = vtk.vtkInteractiveArea()
        view.GetScene().AddItem(area)

        adjusted_plotting_bounds = vcs2vtk.getProjectedBoundsForWorldCoords(
            plotting_dataset_bounds, self._gm.projection)
        drawAreaBounds = vcs2vtk.computeDrawAreaBounds(
            adjusted_plotting_bounds)

        [renWinWidth, renWinHeight] = self._context().renWin.GetSize()
        geom = vtk.vtkRecti(int(round(vp[0] * renWinWidth)),
                            int(round(vp[2] * renWinHeight)),
                            int(round((vp[1] - vp[0]) * renWinWidth)),
                            int(round((vp[3] - vp[2]) * renWinHeight)))

        vcs2vtk.configureContextArea(area, drawAreaBounds, geom)

        for mapper in mappers:
            act = vtk.vtkActor()
            act.SetMapper(mapper)
            mapper.Update()
            poly = mapper.GetInput()

            item = None

            wireframe = False
            if hasattr(mapper, "_useWireFrame"):
                wireframe = True

            if wireframe:
                item = vtk.vtkPolyDataItem()
                item.SetPolyData(poly)

                colorArray = vtk.vtkUnsignedCharArray()
                colorArray.SetNumberOfComponents(4)
                for i in range(poly.GetNumberOfCells()):
                    colorArray.InsertNextTypedTuple(wireColor)

                item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
                item.SetMappedColors(colorArray)
                area.GetDrawAreaItem().AddItem(item)
            elif style == "solid":
                if self._needsCellData:
                    attrs = poly.GetCellData()
                else:
                    attrs = poly.GetPointData()

                data = attrs.GetScalars()
                deleteColors = False

                if data:
                    lut = mapper.GetLookupTable()
                    scalarRange = mapper.GetScalarRange()
                    lut.SetRange(scalarRange)
                    mappedColors = lut.MapScalars(data,
                                                  vtk.VTK_COLOR_MODE_DEFAULT,
                                                  0)
                    deleteColors = True
                else:
                    loc = 'point'
                    numTuples = poly.GetNumberOfPoints()
                    if self._needsCellData:
                        loc = 'cell'
                        numTuples = poly.GetNumberOfCells()
                    msg = 'WARNING: meshfill pipeline: poly does not have Scalars '
                    msg = msg + 'array on {0} data, using solid color'.format(
                        loc)
                    print(msg)
                    color = [0, 0, 0, 255]
                    mappedColors = vcs2vtk.generateSolidColorArray(
                        numTuples, color)

                mappedColors.SetName('Colors')

                item = vtk.vtkPolyDataItem()
                item.SetPolyData(poly)

                if self._needsCellData:
                    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
                else:
                    item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_POINT_DATA)

                item.SetMappedColors(mappedColors)
                if deleteColors:
                    mappedColors.FastDelete()
                area.GetDrawAreaItem().AddItem(item)

            # TODO See comment in boxfill.
            if item is not None:
                if mapper is self._maskedDataMapper:
                    actors.append([
                        item, self._maskedDataMapper, plotting_dataset_bounds
                    ])
                else:
                    actors.append([item, plotting_dataset_bounds])

            if mapper is not self._maskedDataMapper:

                if not wireframe:
                    # Since pattern creation requires a single color, assuming the
                    # first
                    if ctj >= len(tmpColors[cti]):
                        ctj = 0
                        cti += 1
                    c = self.getColorIndexOrRGBA(_colorMap,
                                                 tmpColors[cti][ctj])

                    patact = fillareautils.make_patterned_polydata(
                        poly,
                        fillareastyle=style,
                        fillareaindex=tmpIndices[cti],
                        fillareacolors=c,
                        fillareaopacity=tmpOpacities[cti],
                        fillareapixelspacing=fareapixelspacing,
                        fillareapixelscale=fareapixelscale,
                        size=self._context().renWin.GetSize(),
                        screenGeom=self._context().renWin.GetSize())
                    ctj += 1

                    if patact is not None:
                        actors.append([patact, plotting_dataset_bounds])

                        patMapper = patact.GetMapper()
                        patMapper.Update()
                        patPoly = patMapper.GetInput()

                        patItem = vtk.vtkPolyDataItem()
                        patItem.SetPolyData(patPoly)

                        patItem.SetScalarMode(
                            vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
                        colorArray = patPoly.GetCellData().GetArray('Colors')

                        patItem.SetMappedColors(colorArray)
                        area.GetDrawAreaItem().AddItem(patItem)

                        actors.append([patItem, plotting_dataset_bounds])

        z, t = self.getZandT()

        self._resultDict["vtk_backend_actors"] = actors
        kwargs = {
            "vtk_backend_grid":
            self._vtkDataSet,
            "dataset_bounds":
            self._vtkDataSetBounds,
            "plotting_dataset_bounds":
            plotting_dataset_bounds,
            "vtk_dataset_bounds_no_mask":
            self._vtkDataSetBoundsNoMask,
            "vtk_backend_geo":
            self._vtkGeoTransform,
            "vtk_backend_draw_area_bounds":
            drawAreaBounds,
            "vtk_backend_viewport_scale":
            [self._context_xScale, self._context_yScale]
        }
        if ("ratio_autot_viewport" in self._resultDict):
            kwargs["ratio_autot_viewport"] = vp
        self._resultDict.update(self._context().renderTemplate(
            self._template,
            self._data1,
            self._gm,
            t,
            z,
            X=numpy.arange(min(x1, x2),
                           max(x1, x2) * 1.1,
                           abs(x2 - x1) / 10.),
            Y=numpy.arange(min(y1, y2),
                           max(y1, y2) * 1.1,
                           abs(y2 - y1) / 10.),
            **kwargs))

        legend = getattr(self._gm, "legend", None)

        if self._gm.ext_1:
            if isinstance(self._contourLevels[0], list):
                if numpy.less(abs(self._contourLevels[0][0]), 1.e20):
                    # Ok we need to add the ext levels
                    self._contourLevels.insert(
                        0, [-1.e20, self._contourLevels[0][0]])
            else:
                if numpy.less(abs(self._contourLevels[0]), 1.e20):
                    # need to add an ext
                    self._contourLevels.insert(0, -1.e20)
        if self._gm.ext_2:
            if isinstance(self._contourLevels[-1], list):
                if numpy.less(abs(self._contourLevels[-1][1]), 1.e20):
                    # need ext
                    self._contourLevels.append(
                        [self._contourLevels[-1][1], 1.e20])
            else:
                if numpy.less(abs(self._contourLevels[-1]), 1.e20):
                    # need exts
                    self._contourLevels.append(1.e20)

        patternArgs = {}
        patternArgs['style'] = self._gm.fillareastyle
        patternArgs['index'] = self._gm.fillareaindices
        if patternArgs['index'] is None:
            patternArgs['index'] = [
                1,
            ]
        # Compensate for the different viewport size of the colorbar
        patternArgs['opacity'] = self._gm.fillareaopacity
        patternArgs['pixelspacing'] = [
            int(fareapixelspacing[0] / (vp[1] - vp[0])),
            int(fareapixelspacing[1] / (vp[3] - vp[2]))
        ]
        patternArgs['pixelscale'] = fareapixelscale / (vp[1] - vp[0])
        self._resultDict.update(self._context().renderColorBar(
            self._template, self._contourLevels, self._contourColors, legend,
            self.getColorMap(), **patternArgs))

        projection = vcs.elements["projection"][self._gm.projection]
        kwargs['xaxisconvert'] = self._gm.xaxisconvert
        kwargs['yaxisconvert'] = self._gm.yaxisconvert
        self._context().plotContinents(
            self._plot_kargs.get("continents", self._useContinents),
            plotting_dataset_bounds, projection, self._dataWrapModulo, vp,
            self._template.data.priority, **kwargs)
예제 #6
0
    def _plotInternal(self):
        """Overrides baseclass implementation."""
        # Preserve time and z axis for plotting these inof in rendertemplate
        projection = vcs.elements["projection"][self._gm.projection]

        zaxis, taxis = self.getZandT()

        # Streamline color
        if (not self._gm.coloredbyvector):
            ln_tmp = self._gm.linetype
            if ln_tmp is None:
                ln_tmp = "default"
            try:
                ln_tmp = vcs.getline(ln_tmp)
                lwidth = ln_tmp.width[0]  # noqa
                lcolor = ln_tmp.color[0]
                lstyle = ln_tmp.type[0]  # noqa
            except Exception:
                lstyle = "solid"  # noqa
                lwidth = 1.  # noqa
                lcolor = [0., 0., 0., 100.]
            if self._gm.linewidth is not None:
                lwidth = self._gm.linewidth  # noqa
            if self._gm.linecolor is not None:
                lcolor = self._gm.linecolor

        # The unscaled continent bounds were fine in the presence of axis
        # conversion, so save them here
        continentBounds = vcs2vtk.computeDrawAreaBounds(
            self._vtkDataSetBoundsNoMask, self._context_flipX,
            self._context_flipY)

        # Only scaling the data in the presence of axis conversion changes
        # the seed points in any other cases, and thus results in plots
        # different from the baselines but still fundamentally sound, it
        # seems.  Always scaling the data results in no differences in the
        # plots between Context2D and the old baselines.

        # Transform the input data
        T = vtk.vtkTransform()
        T.Scale(self._context_xScale, self._context_yScale, 1.)

        self._vtkDataSetFittedToViewport = vcs2vtk.applyTransformationToDataset(
            T, self._vtkDataSetFittedToViewport)
        self._vtkDataSetBoundsNoMask = self._vtkDataSetFittedToViewport.GetBounds(
        )

        polydata = self._vtkDataSetFittedToViewport
        plotting_dataset_bounds = self.getPlottingBounds()
        x1, x2, y1, y2 = plotting_dataset_bounds
        vp = self._resultDict.get('ratio_autot_viewport', [
            self._template.data.x1, self._template.data.x2,
            self._template.data.y1, self._template.data.y2
        ])

        # view and interactive area
        view = self._context().contextView
        area = vtk.vtkInteractiveArea()
        view.GetScene().AddItem(area)

        drawAreaBounds = vcs2vtk.computeDrawAreaBounds(
            self._vtkDataSetBoundsNoMask, self._context_flipX,
            self._context_flipY)

        [renWinWidth, renWinHeight] = self._context().renWin.GetSize()
        geom = vtk.vtkRecti(int(round(vp[0] * renWinWidth)),
                            int(round(vp[2] * renWinHeight)),
                            int(round((vp[1] - vp[0]) * renWinWidth)),
                            int(round((vp[3] - vp[2]) * renWinHeight)))

        vcs2vtk.configureContextArea(area, drawAreaBounds, geom)

        dataLength = polydata.GetLength()

        if (not self._gm.evenlyspaced):
            # generate random seeds in a circle centered in the center of
            # the bounding box for the data.

            # by default vtkPointSource uses a global random source in vtkMath which is
            # seeded only once. It makes more sense to seed a random sequence each time you draw
            # the streamline plot.
            pointSequence = vtk.vtkMinimalStandardRandomSequence()
            pointSequence.SetSeedOnly(1177)  # replicate the seed from vtkMath

            seed = vtk.vtkPointSource()
            seed.SetNumberOfPoints(self._gm.numberofseeds)
            seed.SetCenter(polydata.GetCenter())
            seed.SetRadius(dataLength / 2.0)
            seed.SetRandomSequence(pointSequence)
            seed.Update()
            seedData = seed.GetOutput()

            # project all points to Z = 0 plane
            points = seedData.GetPoints()
            for i in range(0, points.GetNumberOfPoints()):
                p = list(points.GetPoint(i))
                p[2] = 0
                points.SetPoint(i, p)

        if (self._gm.integratortype == 0):
            integrator = vtk.vtkRungeKutta2()
        elif (self._gm.integratortype == 1):
            integrator = vtk.vtkRungeKutta4()
        else:
            if (self._gm.evenlyspaced):
                warnings.warn(
                    "You cannot use RungeKutta45 for evenly spaced streamlines."
                    "Using RungeKutta4 instead")
                integrator = vtk.vtkRungeKutta4()
            else:
                integrator = vtk.vtkRungeKutta45()

        if (self._gm.evenlyspaced):
            streamer = vtk.vtkEvenlySpacedStreamlines2D()
            startseed = self._gm.startseed \
                if self._gm.startseed else polydata.GetCenter()
            streamer.SetStartPosition(startseed)
            streamer.SetSeparatingDistance(self._gm.separatingdistance)
            streamer.SetSeparatingDistanceRatio(
                self._gm.separatingdistanceratio)
            streamer.SetClosedLoopMaximumDistance(
                self._gm.closedloopmaximumdistance)
        else:
            # integrate streamlines on normalized vector so that
            # IntegrationTime stores distance
            streamer = vtk.vtkStreamTracer()
            streamer.SetSourceData(seedData)
            streamer.SetIntegrationDirection(self._gm.integrationdirection)
            streamer.SetMinimumIntegrationStep(self._gm.minimumsteplength)
            streamer.SetMaximumIntegrationStep(self._gm.maximumsteplength)
            streamer.SetMaximumError(self._gm.maximumerror)
            streamer.SetMaximumPropagation(dataLength *
                                           self._gm.maximumstreamlinelength)

        streamer.SetInputData(polydata)
        streamer.SetInputArrayToProcess(0, 0, 0, 0, "vector")
        streamer.SetIntegrationStepUnit(self._gm.integrationstepunit)
        streamer.SetInitialIntegrationStep(self._gm.initialsteplength)
        streamer.SetMaximumNumberOfSteps(self._gm.maximumsteps)
        streamer.SetTerminalSpeed(self._gm.terminalspeed)
        streamer.SetIntegrator(integrator)

        # add arc_length to streamlines
        arcLengthFilter = vtk.vtkAppendArcLength()
        arcLengthFilter.SetInputConnection(streamer.GetOutputPort())

        arcLengthFilter.Update()
        streamlines = arcLengthFilter.GetOutput()

        # glyph seed points
        contour = vtk.vtkContourFilter()
        contour.SetInputConnection(arcLengthFilter.GetOutputPort())
        contour.SetValue(0, 0.001)
        if (streamlines.GetNumberOfPoints()):
            r = streamlines.GetPointData().GetArray("arc_length").GetRange()
            numberofglyphsoneside = self._gm.numberofglyphs // 2
            for i in range(1, numberofglyphsoneside):
                contour.SetValue(i, r[1] / numberofglyphsoneside * i)
        else:
            warnings.warn(
                "No streamlines created. "
                "The 'startseed' parameter needs to be inside the domain and "
                "not over masked data.")
        contour.SetInputArrayToProcess(0, 0, 0, 0, "arc_length")

        # arrow glyph source
        glyph2DSource = vtk.vtkGlyphSource2D()
        glyph2DSource.SetGlyphTypeToTriangle()
        glyph2DSource.SetRotationAngle(-90)
        glyph2DSource.SetFilled(self._gm.filledglyph)

        # arrow glyph adjustment
        transform = vtk.vtkTransform()
        transform.Scale(1., self._gm.glyphbasefactor, 1.)
        transformFilter = vtk.vtkTransformFilter()
        transformFilter.SetInputConnection(glyph2DSource.GetOutputPort())
        transformFilter.SetTransform(transform)
        transformFilter.Update()
        glyphLength = transformFilter.GetOutput().GetLength()

        #  drawing the glyphs at the seed points
        glyph = vtk.vtkGlyph2D()
        glyph.SetInputConnection(contour.GetOutputPort())
        glyph.SetInputArrayToProcess(1, 0, 0, 0, "vector")
        glyph.SetSourceData(transformFilter.GetOutput())
        glyph.SetScaleModeToDataScalingOff()
        glyph.SetScaleFactor(dataLength * self._gm.glyphscalefactor /
                             glyphLength)
        glyph.SetColorModeToColorByVector()

        glyphMapper = vtk.vtkPolyDataMapper()
        glyphActor = vtk.vtkActor()

        mapper = vtk.vtkPolyDataMapper()
        act = vtk.vtkActor()

        glyph.Update()
        glyphDataset = glyph.GetOutput()
        streamer.Update()
        lineDataset = streamer.GetOutput()

        deleteLineColors = False
        deleteGlyphColors = False

        # color the streamlines and glyphs
        cmap = self.getColorMap()
        if (self._gm.coloredbyvector):
            numLevels = len(self._contourLevels) - 1
            while len(self._contourColors) < numLevels:
                self._contourColors.append(self._contourColors[-1])

            lut = vtk.vtkLookupTable()
            lut.SetNumberOfTableValues(numLevels)
            for i in range(numLevels):
                r, g, b, a = self.getColorIndexOrRGBA(cmap,
                                                      self._contourColors[i])
                lut.SetTableValue(i, r / 100., g / 100., b / 100., a / 100.)
            lut.SetVectorModeToMagnitude()
            if numpy.allclose(self._contourLevels[0], -1.e20):
                lmn = self._vectorRange[0]
            else:
                lmn = self._contourLevels[0][0]
            if numpy.allclose(self._contourLevels[-1], 1.e20):
                lmx = self._vectorRange[1]
            else:
                lmx = self._contourLevels[-1][-1]
            lut.SetRange(lmn, lmx)

            mapper.ScalarVisibilityOn()
            mapper.SetLookupTable(lut)
            mapper.UseLookupTableScalarRangeOn()
            mapper.SetScalarModeToUsePointFieldData()
            mapper.SelectColorArray("vector")

            lineAttrs = lineDataset.GetPointData()
            lineData = lineAttrs.GetArray("vector")

            if lineData and numLevels:
                lineColors = lut.MapScalars(lineData,
                                            vtk.VTK_COLOR_MODE_DEFAULT, 0)
                deleteLineColors = True
            else:
                print(
                    'WARNING: streamline pipeline cannot map scalars for "lineData", using solid color'
                )
                numTuples = lineDataset.GetNumberOfPoints()
                color = [0, 0, 0, 255]
                lineColors = vcs2vtk.generateSolidColorArray(numTuples, color)

            glyphMapper.ScalarVisibilityOn()
            glyphMapper.SetLookupTable(lut)
            glyphMapper.UseLookupTableScalarRangeOn()
            glyphMapper.SetScalarModeToUsePointFieldData()
            glyphMapper.SelectColorArray("VectorMagnitude")

            glyphAttrs = glyphDataset.GetPointData()
            glyphData = glyphAttrs.GetArray("VectorMagnitude")

            if glyphData and numLevels:
                glyphColors = lut.MapScalars(glyphData,
                                             vtk.VTK_COLOR_MODE_DEFAULT, 0)
                deleteGlyphColors = True
            else:
                print(
                    'WARNING: streamline pipeline cannot map scalars for "glyphData", using solid color'
                )
                numTuples = glyphDataset.GetNumberOfPoints()
                color = [0, 0, 0, 255]
                glyphColors = vcs2vtk.generateSolidColorArray(numTuples, color)
        else:
            mapper.ScalarVisibilityOff()
            glyphMapper.ScalarVisibilityOff()
            if isinstance(lcolor, (list, tuple)):
                r, g, b, a = lcolor
            else:
                r, g, b, a = cmap.index[lcolor]
            act.GetProperty().SetColor(r / 100., g / 100., b / 100.)
            glyphActor.GetProperty().SetColor(r / 100., g / 100., b / 100.)

            fixedColor = [
                int((r / 100.) * 255),
                int((g / 100.) * 255),
                int((b / 100.) * 255), 255
            ]

            numTuples = lineDataset.GetNumberOfPoints()
            lineColors = vcs2vtk.generateSolidColorArray(numTuples, fixedColor)

            numTuples = glyphDataset.GetNumberOfPoints()
            glyphColors = vcs2vtk.generateSolidColorArray(
                numTuples, fixedColor)

        # Add the streamlines
        lineItem = vtk.vtkPolyDataItem()
        lineItem.SetPolyData(lineDataset)
        lineItem.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_POINT_DATA)
        lineItem.SetMappedColors(lineColors)
        if deleteLineColors:
            lineColors.FastDelete()
        area.GetDrawAreaItem().AddItem(lineItem)

        # Add the glyphs
        glyphItem = vtk.vtkPolyDataItem()
        glyphItem.SetPolyData(glyphDataset)
        glyphItem.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_POINT_DATA)
        glyphItem.SetMappedColors(glyphColors)
        if deleteGlyphColors:
            glyphColors.FastDelete()
        area.GetDrawAreaItem().AddItem(glyphItem)

        plotting_dataset_bounds = self.getPlottingBounds()
        vp = self._resultDict.get('ratio_autot_viewport', [
            self._template.data.x1, self._template.data.x2,
            self._template.data.y1, self._template.data.y2
        ])

        kwargs = {
            'vtk_backend_grid':
            self._vtkDataSet,
            'dataset_bounds':
            self._vtkDataSetBounds,
            'plotting_dataset_bounds':
            plotting_dataset_bounds,
            "vtk_dataset_bounds_no_mask":
            self._vtkDataSetBoundsNoMask,
            'vtk_backend_geo':
            self._vtkGeoTransform,
            "vtk_backend_draw_area_bounds":
            continentBounds,
            "vtk_backend_viewport_scale":
            [self._context_xScale, self._context_yScale]
        }
        if ('ratio_autot_viewport' in self._resultDict):
            kwargs["ratio_autot_viewport"] = vp
        self._resultDict.update(self._context().renderTemplate(
            self._template, self._data1, self._gm, taxis, zaxis, **kwargs))
        if (self._gm.coloredbyvector):
            self._resultDict.update(self._context().renderColorBar(
                self._template, self._contourLevels, self._contourColors, None,
                self.getColorMap()))

        kwargs['xaxisconvert'] = self._gm.xaxisconvert
        kwargs['yaxisconvert'] = self._gm.yaxisconvert
        if self._data1.getAxis(-1).isLongitude() and self._data1.getAxis(
                -2).isLatitude():
            self._context().plotContinents(
                self._plot_kargs.get("continents", self._useContinents),
                plotting_dataset_bounds, projection, self._dataWrapModulo, vp,
                self._template.data.priority, **kwargs)
        self._resultDict["vtk_backend_actors"] = [[
            lineItem, plotting_dataset_bounds
        ]]
        self._resultDict["vtk_backend_luts"] = [[None, None]]
예제 #7
0
    def _plotInternal(self):
        """Overrides baseclass implementation."""
        tmpLevels = []
        tmpColors = []
        tmpLineWidths = []
        tmpLineTypes = []

        linewidth = self._gm.linewidths
        self.extendAttribute(linewidth, default=1.0)

        linetype = self._gm.linetypes
        self.extendAttribute(linetype, default='solid')

        plotting_dataset_bounds = self.getPlottingBounds()
        x1, x2, y1, y2 = plotting_dataset_bounds

        for i, lv_tmp in enumerate(self._contourLevels):
            if i == 0:
                W = linewidth[i]
                S = linetype[i]
                C = [self._contourColors[i]]
                if lv_tmp == 1.e20:
                    L = [-1.e20]
                else:
                    L = [lv_tmp]
            else:
                if W == linewidth[i] and S == linetype[i]:
                    # Ok same style and width, lets keep going
                    L.append(lv_tmp)
                    C.append(self._contourColors[i])
                else:
                    tmpLevels.append(L)
                    tmpColors.append(C)
                    tmpLineWidths.append(W)
                    tmpLineTypes.append(S)
                    L = [lv_tmp]
                    C = [self._contourColors[i]]
                    W = linewidth[i]
                    S = linetype[i]

        tmpLevels.append(L)
        tmpColors.append(C)
        tmpLineWidths.append(W)
        tmpLineTypes.append(S)

        cots = []
        textprops = []
        luts = []

        actors = []
        mappers = []

        if self._gm.label and (self._gm.text or self._gm.textcolors):
            # Text objects:
            if self._gm.text:
                texts = self._gm.text
                while len(texts) < len(self._contourLevels):
                    texts.append(texts[-1])
            else:
                texts = [None] * len(self._contourLevels)

            # Custom colors:
            if self._gm.textcolors:
                colorOverrides = self._gm.textcolors
                while len(colorOverrides) < len(self._contourLevels):
                    colorOverrides.append(colorOverrides[-1])
            else:
                colorOverrides = [None] * len(self._gm.text)

            # Custom background colors and opacities:
            backgroundColors = self._gm.labelbackgroundcolors
            if backgroundColors:
                while len(backgroundColors) < len(self._contourLevels):
                    backgroundColors.append(backgroundColors[-1])
            backgroundOpacities = self._gm.labelbackgroundopacities
            if backgroundOpacities:
                while len(backgroundOpacities) < len(self._contourLevels):
                    backgroundOpacities.append(backgroundOpacities[-1])
            else:
                backgroundOpacities = [100.0 for lev in self._contourLevels]

        countLevels = 0
        vp = self._resultDict.get(
            'ratio_autot_viewport',
            [self._template.data.x1, self._template.data.x2,
             self._template.data.y1, self._template.data.y2])

        # view and interactive area
        view = self._context().contextView
        area = vtk.vtkInteractiveArea()
        view.GetScene().AddItem(area)

        adjusted_plotting_bounds = vcs2vtk.getProjectedBoundsForWorldCoords(
            plotting_dataset_bounds, self._gm.projection)
        drawAreaBounds = vcs2vtk.computeDrawAreaBounds(adjusted_plotting_bounds)

        [renWinWidth, renWinHeight] = self._context().renWin.GetSize()
        geom = vtk.vtkRecti(int(round(vp[0] * renWinWidth)),
                            int(round(vp[2] * renWinHeight)),
                            int(round((vp[1] - vp[0]) * renWinWidth)),
                            int(round((vp[3] - vp[2]) * renWinHeight)))

        vcs2vtk.configureContextArea(area, drawAreaBounds, geom)

        # FIXME: This render call is needed to work around a bug somewhere in the
        # FIXME: vtkContextTransform code, where the transformation represented by
        # FIXME: Map[To|From]Scene() isn't set up properly until after a render call.
        self._context().renWin.Render()

        for i, l in enumerate(tmpLevels):
            numLevels = len(l)

            cot = vtk.vtkContourFilter()

            cot.SetInputData(self._vtkDataSetFittedToViewport)
            cot.SetNumberOfContours(numLevels)

            for n in range(numLevels):
                cot.SetValue(n, l[n])
            # TODO remove update
            cot.Update()

            lut = vtk.vtkLookupTable()
            lut.SetNumberOfTableValues(len(tmpColors[i]))
            cmap = self.getColorMap()
            for n, col in enumerate(tmpColors[i]):
                r, g, b, a = self.getColorIndexOrRGBA(cmap, col)
                lut.SetTableValue(n, r / 100., g / 100., b / 100., a / 100.)

            # Setup isoline labels
            if self._gm.label:
                # Setup label mapping array:
                tpropMap = vtk.vtkDoubleArray()
                tpropMap.SetNumberOfComponents(1)
                tpropMap.SetNumberOfTuples(numLevels)
                for n, val in enumerate(l):
                    tpropMap.SetTuple(n, [val])

                # Prep text properties:
                tprops = vtk.vtkTextPropertyCollection()
                if self._gm.text or self._gm.textcolors:
                    ttexts = texts[countLevels:(countLevels + len(l))]

                    for idx, tc in enumerate(ttexts):
                        if vcs.queries.istextcombined(tc):
                            tt, to = tuple(tc.name.split(":::"))
                        elif tc is None:
                            tt = "default"
                            to = "default"
                        elif vcs.queries.istexttable(tc):
                            tt = tc.name
                            to = "default"
                        elif vcs.queries.istextorientation(tc):
                            to = tc.name
                            tt = "default"
                        elif isinstance(tc, str):
                            sp = tc.split(":::")
                            if len(sp) == 2:
                                tt = sp[0]
                                to = sp[1]
                            else:  # Hum don't know what do do with this
                                if sp[0] in vcs.listelements("textcombined"):
                                    tc = vcs.gettextcombined(tc)
                                    tt, to = tuple(tc.name.split(":::"))
                                elif sp[0] in vcs.listelements("textorientation"):
                                    to = sp[0]
                                    tt = "default"
                                elif sp[0] in vcs.listelements("texttable"):
                                    tt = sp[0]
                                    to = "default"

                        tt = vcs.createtexttable(None, tt)

                        colorOverride = colorOverrides[countLevels + idx]
                        if colorOverride is not None:
                            tt.color = colorOverride

                        tt = tt.name

                        if backgroundColors is not None:
                            texttbl = vcs.gettexttable(tt)
                            texttbl.backgroundcolor = backgroundColors[countLevels + idx]
                        if backgroundOpacities is not None:
                            texttbl = vcs.gettexttable(tt)
                            texttbl.backgroundopacity = backgroundOpacities[countLevels + idx]
                        tprop = vtk.vtkTextProperty()
                        vcs2vtk.prepTextProperty(tprop,
                                                 self._context().renWin.GetSize(),
                                                 to, tt, cmap=cmap)
                        tprops.AddItem(tprop)
                        if colorOverride is not None:
                            del(vcs.elements["texttable"][tt])
                else:  # No text properties specified. Use the default:
                    tprop = vtk.vtkTextProperty()
                    vcs2vtk.prepTextProperty(tprop,
                                             self._context().renWin.GetSize(),
                                             cmap=cmap)
                    tprop.SetBackgroundOpacity(1.0)
                    tprops.AddItem(tprop)
                textprops.append(tprops)

                item = vtk.vtkLabeledContourPolyDataItem()
                item.SetTextProperties(tprops)
                item.SetTextPropertyMapping(tpropMap)
                item.SetLabelVisibility(1)
                item.SetSkipDistance(self._gm.labelskipdistance)

                mapper = vtk.vtkLabeledContourMapper()
                pdMapper = mapper.GetPolyDataMapper()

                luts.append([lut, [l[0], l[-1], False]])
            else:  # No isoline labels:
                item = vtk.vtkPolyDataItem()
                mapper = vtk.vtkPolyDataMapper()
                pdMapper = mapper
                luts.append([lut, [l[0], l[-1], False]])
            pdMapper.SetLookupTable(lut)
            lut.SetRange(l[0], l[-1])
            pdMapper.SetScalarRange(l[0], l[-1])
            pdMapper.SetScalarModeToUsePointData()

            stripper = vtk.vtkStripper()
            stripper.SetInputConnection(cot.GetOutputPort())
            mapper.SetInputConnection(stripper.GetOutputPort())
            # TODO remove update, make pipeline
            stripper.Update()
            poly = stripper.GetOutput()
            mappers.append(mapper)
            cots.append(cot)

            if self._needsCellData:
                attrs = poly.GetCellData()
                scalarMode = vtk.VTK_SCALAR_MODE_USE_CELL_DATA
            else:
                attrs = poly.GetPointData()
                scalarMode = vtk.VTK_SCALAR_MODE_USE_POINT_DATA

            data = attrs.GetScalars()
            mappedColors = lut.MapScalars(data, vtk.VTK_COLOR_MODE_DEFAULT, 0)

            intValue = vtk.vtkIntArray()
            intValue.SetNumberOfComponents(1)
            intValue.SetName("StippleType")
            intValue.InsertNextValue(vcs2vtk.getStipple(tmpLineTypes[i]))
            poly.GetFieldData().AddArray(intValue)

            floatValue = vtk.vtkFloatArray()
            floatValue.SetNumberOfComponents(1)
            floatValue.SetName("LineWidth")
            floatValue.InsertNextValue(tmpLineWidths[i])
            poly.GetFieldData().AddArray(floatValue)

            item.SetPolyData(poly)
            item.SetScalarMode(scalarMode)
            item.SetMappedColors(mappedColors)
            mappedColors.FastDelete()
            area.GetDrawAreaItem().AddItem(item)

            actors.append([item, plotting_dataset_bounds])

            countLevels += len(l)
        if len(textprops) > 0:
            self._resultDict["vtk_backend_contours_labels_text_properties"] = \
                textprops
        if len(luts) > 0:
            if self._gm.label:
                self._resultDict["vtk_backend_labeled_luts"] = luts
            else:
                self._resultDict["vtk_backend_luts"] = luts
        if len(cots) > 0:
            self._resultDict["vtk_backend_contours"] = cots

        if self._maskedDataMapper is not None:
            mappers.insert(0, self._maskedDataMapper)

            self._maskedDataMapper.Update()
            maskedData = self._maskedDataMapper.GetInput()
            maskedColors = vtk.vtkUnsignedCharArray()
            maskedColors.SetNumberOfComponents(4)
            for i in range(poly.GetNumberOfCells()):
                maskedColors.InsertNextTypedTuple([0, 0, 0, 255])
            maskItem = vtk.vtkPolyDataItem()
            maskItem.SetPolyData(maskedData)
            maskItem.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
            maskItem.SetMappedColors(maskedColors)
            area.GetDrawAreaItem().AddItem(maskItem)

            actors.append([maskItem, self._maskedDataMapper, plotting_dataset_bounds])

        self._resultDict["vtk_backend_actors"] = actors

        z, t = self.getZandT()

        kwargs = {
            "vtk_backend_grid": self._vtkDataSet,
            "dataset_bounds": self._vtkDataSetBounds,
            "plotting_dataset_bounds": plotting_dataset_bounds,
            "vtk_dataset_bounds_no_mask": self._vtkDataSetBoundsNoMask,
            "vtk_backend_geo": self._vtkGeoTransform,
            "vtk_backend_draw_area_bounds": drawAreaBounds,
            "vtk_backend_viewport_scale": [
                self._context_xScale,
                self._context_yScale
            ]
        }
        if ("ratio_autot_viewport" in self._resultDict):
            kwargs["ratio_autot_viewport"] = vp
        self._resultDict.update(self._context().renderTemplate(
            self._template,
            self._data1,
            self._gm, t, z, **kwargs))

        projection = vcs.elements["projection"][self._gm.projection]
        kwargs['xaxisconvert'] = self._gm.xaxisconvert
        kwargs['yaxisconvert'] = self._gm.yaxisconvert
        if self._data1.getAxis(-1).isLongitude() and self._data1.getAxis(-2).isLatitude():
            self._context().plotContinents(self._plot_kargs.get("continents", self._useContinents),
                                           plotting_dataset_bounds, projection,
                                           self._dataWrapModulo,
                                           vp, self._template.data.priority, **kwargs)
예제 #8
0
    def _plotInternal(self):
        """Overrides baseclass implementation."""
        preppedCountours = self._prepContours()
        tmpLevels = preppedCountours["tmpLevels"]
        tmpIndices = preppedCountours["tmpIndices"]
        tmpColors = preppedCountours["tmpColors"]
        tmpOpacities = preppedCountours["tmpOpacities"]
        style = self._gm.fillareastyle

        luts = []
        cots = []
        mappers = []
        _colorMap = self.getColorMap()

        plotting_dataset_bounds = self.getPlottingBounds()
        x1, x2, y1, y2 = plotting_dataset_bounds
        fareapixelspacing, fareapixelscale = self._patternSpacingAndScale()

        for i, l in enumerate(tmpLevels):
            # Ok here we are trying to group together levels can be, a join
            # will happen if: next set of levels continues where one left off
            # AND pattern is identical
            mapper = vtk.vtkPolyDataMapper()
            lut = vtk.vtkLookupTable()
            cot = vtk.vtkBandedPolyDataContourFilter()
            cot.ClippingOn()
            # cot.SetInputData(self._vtkPolyDataFilter.GetOutput())
            cot.SetInputData(self._vtkDataSetFittedToViewport)
            cot.SetNumberOfContours(len(l))
            cot.SetClipTolerance(0.)
            for j, v in enumerate(l):
                cot.SetValue(j, v)
            cot.Update()

            cots.append(cot)
            mapper.SetInputConnection(cot.GetOutputPort())
            lut.SetNumberOfTableValues(len(tmpColors[i]))
            for j, color in enumerate(tmpColors[i]):
                r, g, b, a = self.getColorIndexOrRGBA(_colorMap, color)
                if style == 'solid':
                    tmpOpacity = tmpOpacities[j]
                    if tmpOpacity is None:
                        tmpOpacity = a / 100.
                    else:
                        tmpOpacity = tmpOpacities[j] / 100.
                    lut.SetTableValue(j, r / 100., g / 100., b / 100., tmpOpacity)
                else:
                    lut.SetTableValue(j, 1., 1., 1., 0.)
            luts.append([lut, [0, len(l) - 1, True]])
            mapper.SetLookupTable(lut)
            minRange = 0
            maxRange = len(l) - 1
            if (i == 0 and self._scalarRange[0] < l[0]):
                # band 0 is from self._scalarRange[0] to l[0]
                # we don't show band 0
                minRange += 1
            mapper.SetScalarRange(minRange, maxRange)
            mapper.SetScalarModeToUseCellData()
            mappers.append(mapper)

        self._resultDict["vtk_backend_luts"] = luts
        if len(cots) > 0:
            self._resultDict["vtk_backend_contours"] = cots

        numLevels = len(self._contourLevels)
        if mappers == []:  # ok didn't need to have special banded contours
            mapper = vtk.vtkPolyDataMapper()
            mappers = [mapper]
            # Colortable bit
            # make sure length match
            while len(self._contourColors) < len(self._contourLevels):
                self._contourColors.append(self._contourColors[-1])

            lut = vtk.vtkLookupTable()
            lut.SetNumberOfTableValues(numLevels)
            for i in range(numLevels):
                r, g, b, a = self.getColorIndexOrRGBA(_colorMap, self._contourColors[i])
                lut.SetTableValue(i, r / 100., g / 100., b / 100., a / 100.)

            mapper.SetLookupTable(lut)
            if numpy.allclose(self._contourLevels[0], -1.e20):
                lmn = self._min - 1.
            else:
                lmn = self._contourLevels[0]
            if numpy.allclose(self._contourLevels[-1], 1.e20):
                lmx = self._max + 1.
            else:
                lmx = self._contourLevels[-1]
            mapper.SetScalarRange(lmn, lmx)
            self._resultDict["vtk_backend_luts"] = [[lut, [lmn, lmx, True]]]

        if self._maskedDataMapper is not None:
            mappers.insert(0, self._maskedDataMapper)

        # And now we need actors to actually render this thing
        actors = []
        ct = 0
        vp = self._resultDict.get('ratio_autot_viewport',
                                  [self._template.data.x1, self._template.data.x2,
                                   self._template.data.y1, self._template.data.y2])

        # view and interactive area
        view = self._context().contextView
        area = vtk.vtkInteractiveArea()
        view.GetScene().AddItem(area)

        adjusted_plotting_bounds = vcs2vtk.getProjectedBoundsForWorldCoords(
            plotting_dataset_bounds, self._gm.projection)
        drawAreaBounds = vcs2vtk.computeDrawAreaBounds(adjusted_plotting_bounds)

        [renWinWidth, renWinHeight] = self._context().renWin.GetSize()
        geom = vtk.vtkRecti(int(round(vp[0] * renWinWidth)),
                            int(round(vp[2] * renWinHeight)),
                            int(round((vp[1] - vp[0]) * renWinWidth)),
                            int(round((vp[3] - vp[2]) * renWinHeight)))

        vcs2vtk.configureContextArea(area, drawAreaBounds, geom)

        for mapper in mappers:
            act = vtk.vtkActor()
            act.SetMapper(mapper)
            mapper.Update()
            poly = mapper.GetInput()

            if not poly:
                continue

            patact = None
            item = None

            if style == "solid":
                deleteColors = False

                attrs = poly.GetCellData()
                data = attrs.GetScalars()
                if data:
                    lut = mapper.GetLookupTable()
                    scalarRange = mapper.GetScalarRange()
                    lut.SetRange(scalarRange)
                    mappedColors = lut.MapScalars(data, vtk.VTK_COLOR_MODE_DEFAULT, 0)
                    deleteColors = True
                else:
                    print('WARNING: isofill pipeline: poly does not have Scalars array on cell data, using solid color')
                    numTuples = poly.GetNumberOfCells()
                    color = [0, 0, 0, 255]
                    mappedColors = vcs2vtk.generateSolidColorArray(numTuples, color)

                scalarMode = vtk.VTK_SCALAR_MODE_USE_CELL_DATA

                item = vtk.vtkPolyDataItem()
                item.SetPolyData(poly)
                item.SetScalarMode(scalarMode)
                item.SetMappedColors(mappedColors)
                if deleteColors:
                    mappedColors.FastDelete()
                area.GetDrawAreaItem().AddItem(item)

            if mapper is self._maskedDataMapper:
                actors.append([item, self._maskedDataMapper, plotting_dataset_bounds])
            else:
                actors.append([item, plotting_dataset_bounds])

            if mapper is not self._maskedDataMapper:
                # Since pattern creation requires a single color, assuming the first
                c = self.getColorIndexOrRGBA(_colorMap, tmpColors[ct][0])

                patact = fillareautils.make_patterned_polydata(poly,
                                                               fillareastyle=style,
                                                               fillareaindex=tmpIndices[ct],
                                                               fillareacolors=c,
                                                               fillareaopacity=tmpOpacities[ct],
                                                               fillareapixelspacing=fareapixelspacing,
                                                               fillareapixelscale=fareapixelscale,
                                                               size=self._context().renWin.GetSize(),
                                                               screenGeom=[geom[2], geom[3]],
                                                               vpScale=[self._context_xScale, self._context_yScale])

                if patact is not None:
                    patMapper = patact.GetMapper()
                    patMapper.Update()
                    patPoly = patMapper.GetInput()

                    patItem = vtk.vtkPolyDataItem()
                    patItem.SetPolyData(patPoly)

                    patItem.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)
                    colorArray = patPoly.GetCellData().GetArray('Colors')

                    patItem.SetMappedColors(colorArray)
                    area.GetDrawAreaItem().AddItem(patItem)

                    actors.append([patItem, plotting_dataset_bounds])

                # increment the count
                ct += 1

        self._resultDict["vtk_backend_actors"] = actors

        z, t = self.getZandT()

        kwargs = {
            "vtk_backend_grid": self._vtkDataSet,
            "dataset_bounds": self._vtkDataSetBounds,
            "plotting_dataset_bounds": plotting_dataset_bounds,
            "vtk_dataset_bounds_no_mask": self._vtkDataSetBoundsNoMask,
            "vtk_backend_geo": self._vtkGeoTransform,
            "vtk_backend_draw_area_bounds": drawAreaBounds,
            "vtk_backend_viewport_scale": [
                self._context_xScale,
                self._context_yScale
            ]
        }
        if ("ratio_autot_viewport" in self._resultDict):
            kwargs["ratio_autot_viewport"] = vp
        self._resultDict.update(self._context().renderTemplate(
            self._template,
            self._data1,
            self._gm, t, z, **kwargs))
        legend = getattr(self._gm, "legend", None)

        if self._gm.ext_1:
            if isinstance(self._contourLevels[0], list):
                if numpy.less(abs(self._contourLevels[0][0]), 1.e20):
                    # Ok we need to add the ext levels
                    self._contourLevels.insert(
                        0, [-1.e20, self._contourLevels[0][0]])
            else:
                if numpy.less(abs(self._contourLevels[0]), 1.e20):
                    # need to add an ext
                    self._contourLevels.insert(0, -1.e20)
        if self._gm.ext_2:
            if isinstance(self._contourLevels[-1], list):
                if numpy.less(abs(self._contourLevels[-1][1]), 1.e20):
                    # need ext
                    self._contourLevels.append([self._contourLevels[-1][1],
                                                1.e20])
            else:
                if numpy.less(abs(self._contourLevels[-1]), 1.e20):
                    # need exts
                    self._contourLevels.append(1.e20)

        # Compensate for the different viewport size of the colorbar
        legendpixspacing = [int(fareapixelspacing[0] / (vp[1] - vp[0])),
                            int(fareapixelspacing[1] / (vp[3] - vp[2]))]
        legendpixscale = fareapixelscale / (vp[1] - vp[0])

        self._resultDict.update(
            self._context().renderColorBar(self._template, self._contourLevels,
                                           self._contourColors, legend,
                                           self.getColorMap(),
                                           style=style,
                                           index=self._gm.fillareaindices,
                                           opacity=self._gm.fillareaopacity,
                                           pixelspacing=legendpixspacing,
                                           pixelscale=legendpixscale))

        projection = vcs.elements["projection"][self._gm.projection]
        kwargs['xaxisconvert'] = self._gm.xaxisconvert
        kwargs['yaxisconvert'] = self._gm.yaxisconvert
        if self._data1.getAxis(-1).isLongitude() and self._data1.getAxis(-2).isLatitude():
            self._context().plotContinents(self._plot_kargs.get("continents", self._useContinents),
                                           plotting_dataset_bounds, projection,
                                           self._dataWrapModulo,
                                           vp, self._template.data.priority, **kwargs)
예제 #9
0
    def _plotInternal(self):
        """Overrides baseclass implementation."""
        # Preserve time and z axis for plotting these inof in rendertemplate
        projection = vcs.elements["projection"][self._gm.projection]
        zaxis, taxis = self.getZandT()
        scale = 1.0

        if self._vtkGeoTransform is not None:
            lat = None
            lon = None

            latAccessor = self._data1.getLatitude()
            lonAccessor = self._data1.getLongitude()
            if latAccessor:
                lat = latAccessor[:]
            if lonAccessor:
                lon = lonAccessor[:]
            newv = vtk.vtkDoubleArray()
            newv.SetNumberOfComponents(3)
            newv.InsertTypedTuple(0, [lon.min(), lat.min(), 0])
            newv.InsertTypedTuple(1, [lon.max(), lat.max(), 0])

            vcs2vtk.projectArray(newv, projection, self._vtkDataSetBounds)
            dimMin = [0, 0, 0]
            dimMax = [0, 0, 0]

            newv.GetTypedTuple(0, dimMin)
            newv.GetTypedTuple(1, dimMax)

            maxDimX = max(dimMin[0], dimMax[0])
            maxDimY = max(dimMin[1], dimMax[1])

            if lat.max() != 0.0:
                scale = abs((maxDimY / lat.max()))

            if lon.max() != 0.0:
                temp = abs((maxDimX / lon.max()))
                if scale < temp:
                    scale = temp
        else:
            scale = 1.0

        # Vector attempt
        ltp_tmp = self._gm.linetype
        if ltp_tmp is None:
            ltp_tmp = "default"
        try:
            ltp_tmp = vcs.getline(ltp_tmp)
            lwidth = ltp_tmp.width[0]  # noqa
            lcolor = ltp_tmp.color[0]
            lstyle = ltp_tmp.type[0]  # noqa
        except Exception:
            lstyle = "solid"  # noqa
            lwidth = 1.  # noqa
            lcolor = [0., 0., 0., 100.]
        if self._gm.linewidth is not None:
            lwidth = self._gm.linewidth  # noqa
        if self._gm.linecolor is not None:
            lcolor = self._gm.linecolor

        arrow = vtk.vtkGlyphSource2D()
        arrow.SetGlyphTypeToArrow()
        arrow.SetOutputPointsPrecision(vtk.vtkAlgorithm.DOUBLE_PRECISION)
        arrow.FilledOff()

        plotting_dataset_bounds = self.getPlottingBounds()
        x1, x2, y1, y2 = plotting_dataset_bounds
        vp = self._resultDict.get('ratio_autot_viewport', [
            self._template.data.x1, self._template.data.x2,
            self._template.data.y1, self._template.data.y2
        ])

        # The unscaled continent bounds were fine in the presence of axis
        # conversion, so save them here
        adjusted_plotting_bounds = vcs2vtk.getProjectedBoundsForWorldCoords(
            plotting_dataset_bounds, self._gm.projection)
        continentBounds = vcs2vtk.computeDrawAreaBounds(
            adjusted_plotting_bounds)

        # Transform the input data
        T = vtk.vtkTransform()
        T.Scale(self._context_xScale, self._context_yScale, 1.)
        self._vtkDataSetFittedToViewport = vcs2vtk.applyTransformationToDataset(
            T, self._vtkDataSetFittedToViewport)
        self._vtkDataSetBoundsNoMask = self._vtkDataSetFittedToViewport.GetBounds(
        )

        polydata = self._vtkDataSetFittedToViewport

        # view and interactive area
        view = self._context().contextView
        area = vtk.vtkInteractiveArea()
        view.GetScene().AddItem(area)

        drawAreaBounds = vcs2vtk.computeDrawAreaBounds(
            self._vtkDataSetBoundsNoMask, self._context_flipX,
            self._context_flipY)

        [renWinWidth, renWinHeight] = self._context().renWin.GetSize()
        geom = vtk.vtkRecti(int(round(vp[0] * renWinWidth)),
                            int(round(vp[2] * renWinHeight)),
                            int(round((vp[1] - vp[0]) * renWinWidth)),
                            int(round((vp[3] - vp[2]) * renWinHeight)))

        vcs2vtk.configureContextArea(area, drawAreaBounds, geom)

        # polydata = tmpMapper.GetInput()
        plotting_dataset_bounds = self.getPlottingBounds()

        vectors = polydata.GetPointData().GetVectors()

        if self._gm.scaletype == 'constant' or\
           self._gm.scaletype == 'constantNNormalize' or\
           self._gm.scaletype == 'constantNLinear':
            scaleFactor = scale * self._gm.scale
        else:
            scaleFactor = 1.0

        glyphFilter = vtk.vtkGlyph2D()
        glyphFilter.SetInputArrayToProcess(1, 0, 0, 0, "vector")
        glyphFilter.SetSourceConnection(arrow.GetOutputPort())
        glyphFilter.SetVectorModeToUseVector()

        # Rotate arrows to match vector data:
        glyphFilter.OrientOn()
        glyphFilter.ScalingOn()

        glyphFilter.SetScaleModeToScaleByVector()

        maxNormInVp = None
        minNormInVp = None
        # Find the min and max vector magnitudes
        (minNorm, maxNorm) = vectors.GetRange(-1)
        if maxNorm == 0:
            maxNorm = 1.0

        if self._gm.scaletype == 'normalize' or self._gm.scaletype == 'linear' or\
           self._gm.scaletype == 'constantNNormalize' or self._gm.scaletype == 'constantNLinear':
            if self._gm.scaletype == 'normalize' or self._gm.scaletype == 'constantNNormalize':
                scaleFactor /= maxNorm

            if self._gm.scaletype == 'linear' or self._gm.scaletype == 'constantNLinear':
                noOfComponents = vectors.GetNumberOfComponents()
                scalarArray = vtk.vtkDoubleArray()
                scalarArray.SetNumberOfComponents(1)
                scalarArray.SetNumberOfValues(vectors.GetNumberOfTuples())

                oldRange = maxNorm - minNorm
                oldRange = 1.0 if oldRange == 0.0 else oldRange

                # New range min, max.
                newRangeValues = self._gm.scalerange
                newRange = newRangeValues[1] - newRangeValues[0]

                for i in range(0, vectors.GetNumberOfTuples()):
                    norm = vtk.vtkMath.Norm(vectors.GetTuple(i),
                                            noOfComponents)
                    newValue = (((norm - minNorm) * newRange) /
                                oldRange) + newRangeValues[0]
                    scalarArray.SetValue(i, newValue)

                polydata.GetPointData().SetScalars(scalarArray)
                maxNormInVp = newRangeValues[1] * scaleFactor
                minNormInVp = newRangeValues[0] * scaleFactor

                # Scale to vector magnitude:
                # NOTE: Currently we compute our own scaling factor since VTK does
                # it by clamping the values > max to max  and values < min to min
                # and not remap the range.
                glyphFilter.SetScaleModeToScaleByScalar()

        if (maxNormInVp is None):
            maxNormInVp = maxNorm * scaleFactor
            # minNormInVp is left None, as it is displayed only for linear scaling.

        cmap = self.getColorMap()
        if isinstance(lcolor, (list, tuple)):
            r, g, b, a = lcolor
        else:
            r, g, b, a = cmap.index[lcolor]
        # act.GetProperty().SetColor(r / 100., g / 100., b / 100.)
        vtk_color = [int((c / 100.) * 255) for c in [r, g, b, a]]

        # Using the scaled data, set the glyph filter input
        glyphFilter.SetScaleFactor(scaleFactor)
        glyphFilter.SetInputData(polydata)
        glyphFilter.Update()
        # and set the arrows to be rendered.

        data = glyphFilter.GetOutput()

        floatValue = vtk.vtkFloatArray()
        floatValue.SetNumberOfComponents(1)
        floatValue.SetName("LineWidth")
        floatValue.InsertNextValue(lwidth)
        data.GetFieldData().AddArray(floatValue)

        item = vtk.vtkPolyDataItem()
        item.SetPolyData(data)

        item.SetScalarMode(vtk.VTK_SCALAR_MODE_USE_CELL_DATA)

        colorArray = vtk.vtkUnsignedCharArray()
        colorArray.SetNumberOfComponents(4)
        for i in range(data.GetNumberOfCells()):
            colorArray.InsertNextTypedTuple(vtk_color)

        item.SetMappedColors(colorArray)
        area.GetDrawAreaItem().AddItem(item)

        kwargs = {
            'vtk_backend_grid':
            self._vtkDataSet,
            'dataset_bounds':
            self._vtkDataSetBounds,
            'plotting_dataset_bounds':
            plotting_dataset_bounds,
            "vtk_dataset_bounds_no_mask":
            self._vtkDataSetBoundsNoMask,
            'vtk_backend_geo':
            self._vtkGeoTransform,
            "vtk_backend_draw_area_bounds":
            continentBounds,
            "vtk_backend_viewport_scale":
            [self._context_xScale, self._context_yScale]
        }
        if ('ratio_autot_viewport' in self._resultDict):
            kwargs["ratio_autot_viewport"] = vp
        self._resultDict.update(self._context().renderTemplate(
            self._template, self._data1, self._gm, taxis, zaxis, **kwargs))

        # assume that self._data1.units has the proper vector units
        unitString = None
        if (hasattr(self._data1, 'units')):
            unitString = self._data1.units

        if self._vtkGeoTransform:
            worldWidth = self._vtkDataSetBoundsNoMask[
                1] - self._vtkDataSetBoundsNoMask[0]
        else:
            worldWidth = self._vtkDataSetBounds[1] - self._vtkDataSetBounds[0]

        worldToViewportXScale = (vp[1] - vp[0]) / worldWidth
        maxNormInVp *= worldToViewportXScale
        if (minNormInVp):
            minNormInVp *= worldToViewportXScale
        vcs.utils.drawVectorLegend(self._context().canvas,
                                   self._template.legend,
                                   lcolor,
                                   lstyle,
                                   lwidth,
                                   unitString,
                                   maxNormInVp,
                                   maxNorm,
                                   minNormInVp,
                                   minNorm,
                                   reference=self._gm.reference)

        kwargs['xaxisconvert'] = self._gm.xaxisconvert
        kwargs['yaxisconvert'] = self._gm.yaxisconvert
        if self._data1.getAxis(-1).isLongitude() and self._data1.getAxis(
                -2).isLatitude():
            self._context().plotContinents(
                self._plot_kargs.get("continents", self._useContinents),
                plotting_dataset_bounds, projection, self._dataWrapModulo, vp,
                self._template.data.priority, **kwargs)
        self._resultDict["vtk_backend_actors"] = [[
            item, plotting_dataset_bounds
        ]]
        self._resultDict["vtk_backend_glyphfilters"] = [glyphFilter]
        self._resultDict["vtk_backend_luts"] = [[None, None]]