Exemplo n.º 1
0
    def getSortedOrderArray(self):
        sortedOrder = vtkUnsignedCharArray()
        sortedOrder.SetName("layerIdx")
        sortedOrder.SetNumberOfTuples(self.stackSize)

        # Reset content
        for idx in range(self.stackSize):
            sortedOrder.SetValue(idx, 255)

        idx = 0
        for pixel in self.pixels:
            x = idx % self.width
            y = idx / self.width
            flipYIdx = self.width * (self.height - y - 1) + x
            if "@" in pixel:
                idx += int(pixel[1:])
            else:
                # Need to decode the order
                layerIdx = 0
                for layer in pixel:
                    sortedOrder.SetValue(flipYIdx + self.imageSize * layerIdx,
                                         self.encoding.index(layer))
                    layerIdx += 1

                # Move to next pixel
                idx += 1

        return sortedOrder
Exemplo n.º 2
0
    def getLookupTableForArrayName(self, name, numSamples=255):
        lutProxy = simple.GetColorTransferFunction(name)
        lut = lutProxy.GetClientSideObject()
        dataRange = lut.GetRange()
        delta = (dataRange[1] - dataRange[0]) / float(numSamples)

        colorArray = vtkUnsignedCharArray()
        colorArray.SetNumberOfComponents(3)
        colorArray.SetNumberOfTuples(numSamples)

        rgb = [0, 0, 0]
        for i in range(numSamples):
            lut.GetColor(dataRange[0] + float(i) * delta, rgb)
            r = int(round(rgb[0] * 255))
            g = int(round(rgb[1] * 255))
            b = int(round(rgb[2] * 255))
            colorArray.SetTuple3(i, r, g, b)

        # Add the color array to an image data
        imgData = vtkImageData()
        imgData.SetDimensions(numSamples, 1, 1)
        aIdx = imgData.GetPointData().SetScalars(colorArray)

        # Use the vtk data encoder to base-64 encode the image as png, using no compression
        encoder = vtkDataEncoder()
        # two calls in a row crash on Windows - bald timing hack to avoid the crash.
        time.sleep(0.01)
        b64Str = encoder.EncodeAsBase64Jpg(imgData, 100)

        return {
            "image": "data:image/jpg;base64," + b64Str,
            "range": dataRange,
            "name": name,
        }
Exemplo n.º 3
0
    def writeLightArray(self, path, source):
        rep = simple.Show(source, self.view)
        rep.Representation = 'Surface'
        rep.DiffuseColor = [1, 1, 1]
        simple.ColorBy(rep, ('POINTS', None))

        # Grab data
        tmpFileName = path + '__.png'
        self.view.LockBounds = 1
        simple.SaveScreenshot(tmpFileName, self.view)
        self.view.LockBounds = 0

        if self.canWrite:
            # Convert data
            self.reader.SetFileName(tmpFileName)
            self.reader.Update()

            rgbArray = self.reader.GetOutput().GetPointData().GetArray(0)
            arraySize = rgbArray.GetNumberOfTuples()

            rawArray = vtkUnsignedCharArray()
            rawArray.SetNumberOfTuples(arraySize)

            for idx in range(arraySize):
                light = rgbArray.GetTuple3(idx)[0]
                rawArray.SetTuple1(idx, light)

            with open(path, 'wb') as f:
                f.write(buffer(rawArray))

            # Delete temporary file
            if self.cleanAfterMe:
                os.remove(tmpFileName)

        simple.Hide(source, self.view)
Exemplo n.º 4
0
    def getSortedOrderArray(self):
        sortedOrder = vtkUnsignedCharArray()
        sortedOrder.SetName('layerIdx');
        sortedOrder.SetNumberOfTuples(self.stackSize)

        # Reset content
        for idx in range(self.stackSize):
            sortedOrder.SetValue(idx, 255)

        idx = 0
        for pixel in self.pixels:
            x = (idx % self.width)
            y = (idx / self.width)
            flipYIdx = self.width * (self.height - y - 1) + x
            if '@' in pixel:
                idx += int(pixel[1:])
            else:
                # Need to decode the order
                layerIdx = 0
                for layer in pixel:
                    sortedOrder.SetValue(flipYIdx + self.imageSize * layerIdx, self.encoding.index(layer))
                    layerIdx += 1

                # Move to next pixel
                idx += 1

        return sortedOrder
Exemplo n.º 5
0
    def writeLightArray(self, path, source):
        rep = simple.Show(source, self.view)
        rep.Representation = 'Surface'
        rep.DiffuseColor = [1,1,1]
        simple.ColorBy(rep, ('POINTS', None))

        # Grab data
        tmpFileName = path + '__.png'
        self.view.LockBounds = 1
        simple.SaveScreenshot(tmpFileName, self.view)
        self.view.LockBounds = 0

        if self.canWrite:
            # Convert data
            self.reader.SetFileName(tmpFileName)
            self.reader.Update()

            rgbArray = self.reader.GetOutput().GetPointData().GetArray(0)
            arraySize = rgbArray.GetNumberOfTuples()

            rawArray = vtkUnsignedCharArray()
            rawArray.SetNumberOfTuples(arraySize)

            for idx in range(arraySize):
                light = rgbArray.GetTuple3(idx)[0]
                rawArray.SetTuple1(idx, light)

            with open(path, 'wb') as f:
                f.write(buffer(rawArray))

            # Delete temporary file
            if self.cleanAfterMe:
                os.remove(tmpFileName)

        simple.Hide(source, self.view)
Exemplo n.º 6
0
    def pushSaturation(self, saturationFile):
        if os.path.exists(saturationFile):
            self.pfbReader.FileNames = [saturationFile]
            self.pfbReader.UpdatePipeline()
            imageData = self.pfbReader.GetClientSideObject().GetOutput(
            ).GetBlock(0)
            array = imageData.GetCellData().GetArray(0)
            size = array.GetNumberOfTuples()

            # Data convertion
            saturationArray = vtkUnsignedCharArray()
            saturationArray.SetNumberOfTuples(size)
            for i in range(size):
                value = array.GetValue(i)
                if value >= 1.0:
                    saturationArray.SetValue(i, 255)
                elif value < 0.0:
                    saturationArray.SetValue(i, 0)
                else:
                    saturationArray.SetValue(i, int(value * 255))
            print('push saturation: %s' % saturationFile)
            self.publish(
                'parflow.sandtank.saturation', {
                    'time': self.lastProcessedTimestep,
                    'array': self.addAttachment(
                        buffer(saturationArray).tobytes())
                })
Exemplo n.º 7
0
    def pushIndicator(self):
        filePath = os.path.join(self.workdir, 'SandTank_Indicator.pfb')
        if not os.path.exists(filePath):
            print('no file for indicator')
            return None

        if self.pfbReader:
            self.pfbReader.FileNames = [filePath]
        else:
            self.pfbReader = simple.PFBreader(FileNames=[filePath],
                                              IsCLMFile='No')
        self.pfbReader.UpdatePipeline()

        imageData = self.pfbReader.GetClientSideObject().GetOutput().GetBlock(
            0)
        imageSize = [v - 1 for v in imageData.GetDimensions()]
        array = imageData.GetCellData().GetArray(0)
        size = array.GetNumberOfTuples()

        indicatorDimensions = imageSize
        indicatorArray = vtkUnsignedCharArray()
        indicatorArray.SetNumberOfTuples(size)
        for i in range(size):
            indicatorArray.SetValue(i, int(array.GetValue(i)))

        self.publish(
            'parflow.sandtank.indicator', {
                'dimensions': indicatorDimensions,
                'array': self.addAttachment(buffer(indicatorArray).tobytes()),
            })

        # Schedule file processing...
        self.processNextFile()
Exemplo n.º 8
0
def compute_tubes(trk, direction):
    """Compute and assign colors to a vtkTube for visualization of a single tract

    :param trk: nx3 array of doubles (x, y, z) point coordinates composing the tract
    :type trk: numpy.ndarray
    :param direction: nx3 array of int (x, y, z) RGB colors in the range 0 - 255
    :type direction: numpy.ndarray
    :return: a vtkTubeFilter instance
    :rtype: vtkTubeFilter
    """

    numb_points = trk.shape[0]
    points = vtkPoints()
    lines = vtkCellArray()

    colors = vtkUnsignedCharArray()
    colors.SetNumberOfComponents(4)

    k = 0
    lines.InsertNextCell(numb_points)
    for j in range(numb_points):
        points.InsertNextPoint(trk[j, :])
        colors.InsertNextTuple(direction[j, :])
        lines.InsertCellPoint(k)
        k += 1

    trk_data = vtkPolyData()
    trk_data.SetPoints(points)
    trk_data.SetLines(lines)
    trk_data.GetPointData().SetScalars(colors)

    # make it a tube
    trk_tube = vtkTubeFilter()
    trk_tube.SetRadius(0.5)
    trk_tube.SetNumberOfSides(4)
    trk_tube.SetInputData(trk_data)
    trk_tube.Update()

    return trk_tube
Exemplo n.º 9
0
    def convert(self, directory):
        imagePaths = {}
        depthPaths = {}
        layerNames = []
        for fileName in os.listdir(directory):
            if "_rgb" in fileName or "_depth" in fileName:
                fileId = fileName.split("_")[0][0]
                if "_rgb" in fileName:
                    imagePaths[fileId] = os.path.join(directory, fileName)
                else:
                    layerNames.append(fileId)
                    depthPaths[fileId] = os.path.join(directory, fileName)

        layerNames.sort()

        if len(layerNames) == 0:
            return

        # Load data in Memory
        depthArrays = []
        imageReader = vtkPNGReader()
        numberOfValues = self.width * self.height * len(layerNames)
        imageSize = self.width * self.height
        self.layers = len(layerNames)

        # Write all images as single memoryview
        opacity = vtkUnsignedCharArray()
        opacity.SetNumberOfComponents(1)
        opacity.SetNumberOfTuples(numberOfValues)

        intensity = vtkUnsignedCharArray()
        intensity.SetNumberOfComponents(1)
        intensity.SetNumberOfTuples(numberOfValues)

        for layer in range(self.layers):
            imageReader.SetFileName(imagePaths[layerNames[layer]])
            imageReader.Update()

            rgbaArray = imageReader.GetOutput().GetPointData().GetArray(0)

            for idx in range(imageSize):
                intensity.SetValue((layer * imageSize) + idx,
                                   rgbaArray.GetValue(idx * 4))
                opacity.SetValue((layer * imageSize) + idx,
                                 rgbaArray.GetValue(idx * 4 + 3))

            with open(depthPaths[layerNames[layer]], "rb") as depthFile:
                depthArrays.append(depthFile.read())

        # Apply pixel sorting
        destOrder = vtkUnsignedCharArray()
        destOrder.SetNumberOfComponents(1)
        destOrder.SetNumberOfTuples(numberOfValues)

        opacityOrder = vtkUnsignedCharArray()
        opacityOrder.SetNumberOfComponents(1)
        opacityOrder.SetNumberOfTuples(numberOfValues)

        intensityOrder = vtkUnsignedCharArray()
        intensityOrder.SetNumberOfComponents(1)
        intensityOrder.SetNumberOfTuples(numberOfValues)

        for pixelIdx in range(imageSize):
            depthStack = []
            for depthArray in depthArrays:
                depthStack.append((depthArray[pixelIdx], len(depthStack)))
            depthStack.sort(key=lambda tup: tup[0])

            for destLayerIdx in range(len(depthStack)):
                sourceLayerIdx = depthStack[destLayerIdx][1]

                # Copy Idx
                destOrder.SetValue((imageSize * destLayerIdx) + pixelIdx,
                                   sourceLayerIdx)
                opacityOrder.SetValue(
                    (imageSize * destLayerIdx) + pixelIdx,
                    opacity.GetValue((imageSize * sourceLayerIdx) + pixelIdx),
                )
                intensityOrder.SetValue(
                    (imageSize * destLayerIdx) + pixelIdx,
                    intensity.GetValue((imageSize * sourceLayerIdx) +
                                       pixelIdx),
                )

        with open(os.path.join(directory, "alpha.uint8"), "wb") as f:
            f.write(memoryview(opacityOrder))

        with open(os.path.join(directory, "intensity.uint8"), "wb") as f:
            f.write(memoryview(intensityOrder))

        with open(os.path.join(directory, "order.uint8"), "wb") as f:
            f.write(memoryview(destOrder))
Exemplo n.º 10
0
    def testHypterTreeGridMask(self):
        "Test a simple hyper tree grid with masking"

        htg = vtkHyperTreeGrid()

        scalarArray = vtkUnsignedCharArray()
        scalarArray.SetName('scalar')
        scalarArray.SetNumberOfValues(0)

        mask = vtkBitArray()
        mask.SetName('mask')
        mask.SetNumberOfValues(22)
        mask.FillComponent(0, 0)
        htg.SetMaterialMask(mask)

        htg.GetPointData().SetScalars(scalarArray)

        htg.Initialize()
        htg.SetGridSize([3, 2, 1])
        htg.SetDimension(2)
        htg.SetBranchFactor(2)
        # specify normal index to ignore
        htg.SetOrientation(2)
        # htg.SetTransposedRootIndexing(False)

        # rectilinear grid coordinates
        xValues = vtkDoubleArray()
        xValues.SetNumberOfValues(4)
        xValues.SetValue(0, -1)
        xValues.SetValue(1, 0)
        xValues.SetValue(2, 1)
        xValues.SetValue(3, 2)
        htg.SetXCoordinates(xValues)

        yValues = vtkDoubleArray()
        yValues.SetNumberOfValues(3)
        yValues.SetValue(0, -1)
        yValues.SetValue(1, 0)
        yValues.SetValue(2, 1)
        htg.SetYCoordinates(yValues)

        zValues = vtkDoubleArray()
        zValues.SetNumberOfValues(1)
        zValues.SetValue(0, 0)
        htg.SetZCoordinates(zValues)

        # Let's split the various trees
        cursor = vtkHyperTreeGridNonOrientedCursor()
        offsetIndex = 0

        # ROOT CELL 0
        htg.InitializeNonOrientedCursor(cursor, 0, True)
        cursor.SetGlobalIndexStart(offsetIndex)

        # coarse value
        idx = cursor.GetGlobalNodeIndex()

        # GLOBAL...
        # cursor.SetGlobalIndexFromLocal(idx)

        scalarArray.InsertTuple1(idx, 0)

        # ROOT CELL 0/[0-3]
        cursor.SubdivideLeaf()
        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 24)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 27)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 18)
        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 21)
        cursor.ToParent()

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 1
        htg.InitializeNonOrientedCursor(cursor, 1, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 15)

        # Mask
        mask.SetValue(idx, 1)

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 2
        htg.InitializeNonOrientedCursor(cursor, 2, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 2)

        # Mask
        mask.SetValue(idx, 1)

        # ROOT CELL 2/[0-3]
        cursor.SubdivideLeaf()
        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 36)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 39)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 30)

        # Mask
        mask.SetValue(idx, 1)

        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 33)
        cursor.ToParent()

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 3
        htg.InitializeNonOrientedCursor(cursor, 3, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 0)

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 4
        htg.InitializeNonOrientedCursor(cursor, 4, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 4)

        # ROOT CELL 4/[0-3]
        cursor.SubdivideLeaf()
        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 9)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 12)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 3)
        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 51)
        cursor.ToParent()

        # ROOT CELL 4/3/[0-3]
        cursor.ToChild(3)
        cursor.SubdivideLeaf()

        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 45)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 51)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 6)
        # Mask
        mask.SetValue(idx, 1)
        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 45)
        cursor.ToParent()

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 5
        htg.InitializeNonOrientedCursor(cursor, 5, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 42)

        # ---------------------------------------------------------------------
        # Convert HTG to PolyData
        # ---------------------------------------------------------------------

        geometryFilter = vtkHyperTreeGridGeometry()
        geometryFilter.SetInputData(htg)

        # ---------------------------------------------------------------------
        # Rendering
        # ---------------------------------------------------------------------

        ren1 = vtk.vtkRenderer()
        renWin = vtk.vtkRenderWindow()
        renWin.AddRenderer(ren1)
        iren = vtk.vtkRenderWindowInteractor()
        iren.SetRenderWindow(renWin)

        lut = vtk.vtkLookupTable()
        lut.SetHueRange(0.66, 0)
        lut.SetSaturationRange(1.0, 0.25)
        lut.SetTableRange(0, 51)
        lut.Build()

        mapper = vtk.vtkDataSetMapper()
        mapper.SetLookupTable(lut)
        mapper.SetColorModeToMapScalars()
        mapper.SetScalarModeToUseCellFieldData()
        mapper.SelectColorArray('scalar')
        mapper.SetInputConnection(geometryFilter.GetOutputPort())
        mapper.UseLookupTableScalarRangeOn()
        mapper.SetScalarRange(0, 51)

        actor = vtk.vtkActor()
        actor.SetMapper(mapper)

        ren1.AddActor(actor)
        renWin.SetSize(350, 350)
        ren1.SetBackground(0.5, 0.5, 0.5)
        ren1.ResetCamera()
        renWin.Render()

        img_file = "TestHyperTreeGridMask.png"
        vtk.test.Testing.compareImage(
            renWin, vtk.test.Testing.getAbsImagePath(img_file), threshold=25)
        vtk.test.Testing.interact()
Exemplo n.º 11
0
    def processDirectory(self, directory):
        # Load depth
        depthStack = []
        imageSize = self.config["size"]
        linearSize = imageSize[0] * imageSize[1]
        nbLayers = len(self.layers)
        stackSize = nbLayers * linearSize
        layerList = range(nbLayers)
        for layerIdx in layerList:
            with open(os.path.join(directory, "depth_%d.float32" % layerIdx),
                      "rb") as f:
                a = array.array("f")
                a.fromfile(f, linearSize)
                depthStack.append(a)

        orderArray = vtkUnsignedCharArray()
        orderArray.SetName("layerIdx")
        orderArray.SetNumberOfComponents(1)
        orderArray.SetNumberOfTuples(stackSize)

        pixelSorter = [(i, i) for i in layerList]

        for pixelId in range(linearSize):
            # Fill pixelSorter
            for layerIdx in layerList:
                if depthStack[layerIdx][pixelId] < 1.0:
                    pixelSorter[layerIdx] = (layerIdx,
                                             depthStack[layerIdx][pixelId])
                else:
                    pixelSorter[layerIdx] = (255, 1.0)

            # Sort pixel layers
            pixelSorter.sort(key=lambda tup: tup[1])

            # Fill sortedOrder array
            for layerIdx in layerList:
                orderArray.SetValue(layerIdx * linearSize + pixelId,
                                    pixelSorter[layerIdx][0])

        # Write order (sorted order way)
        with open(os.path.join(directory, "order.uint8"), "wb") as f:
            f.write(memoryview(orderArray))
            self.data.append({
                "name": "order",
                "type": "array",
                "fileName": "/order.uint8"
            })

        # Remove depth files
        for layerIdx in layerList:
            os.remove(os.path.join(directory, "depth_%d.float32" % layerIdx))

        # Encode Normals (sorted order way)
        if "normal" in self.config["light"]:
            sortedNormal = vtkUnsignedCharArray()
            sortedNormal.SetNumberOfComponents(3)  # x,y,z
            sortedNormal.SetNumberOfTuples(stackSize)

            # Get Camera orientation and rotation information
            camDir = [0, 0, 0]
            worldUp = [0, 0, 0]
            with open(os.path.join(directory, "camera.json"), "r") as f:
                camera = json.load(f)
                camDir = normalize([
                    camera["position"][i] - camera["focalPoint"][i]
                    for i in range(3)
                ])
                worldUp = normalize(camera["viewUp"])

            # [ camRight, camUp, camDir ] will be our new orthonormal basis for normals
            camRight = vectProduct(camDir, worldUp)
            camUp = vectProduct(camRight, camDir)

            # Tmp structure to capture (x,y,z) normal
            normalByLayer = vtkFloatArray()
            normalByLayer.SetNumberOfComponents(3)
            normalByLayer.SetNumberOfTuples(stackSize)

            # Capture all layer normals
            zPosCount = 0
            zNegCount = 0
            for layerIdx in layerList:

                # Load normal(x,y,z) from current layer
                normalLayer = []
                for comp in [0, 1, 2]:
                    with open(
                            os.path.join(
                                directory,
                                "normal_%d_%d.float32" % (layerIdx, comp)),
                            "rb",
                    ) as f:
                        a = array.array("f")
                        a.fromfile(f, linearSize)
                        normalLayer.append(a)

                # Store normal inside vtkArray
                offset = layerIdx * linearSize
                for idx in range(linearSize):
                    normalByLayer.SetTuple3(
                        idx + offset,
                        normalLayer[0][idx],
                        normalLayer[1][idx],
                        normalLayer[2][idx],
                    )

                    # Re-orient normal to be view based
                    vect = normalByLayer.GetTuple3(layerIdx * linearSize + idx)
                    if not math.isnan(vect[0]):
                        # Express normal in new basis we computed above
                        rVect = normalize([
                            -dotProduct(vect, camRight),
                            dotProduct(vect, camUp),
                            dotProduct(vect, camDir),
                        ])

                        # Need to reverse vector ?
                        if rVect[2] < 0:
                            normalByLayer.SetTuple3(
                                layerIdx * linearSize + idx,
                                -rVect[0],
                                -rVect[1],
                                -rVect[2],
                            )
                        else:
                            normalByLayer.SetTuple3(
                                layerIdx * linearSize + idx,
                                rVect[0],
                                rVect[1],
                                rVect[2],
                            )

            # Sort normals and encode them as 3 bytes ( -1 < xy < 1 | 0 < z < 1)
            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    # No normal => same as view direction
                    sortedNormal.SetTuple3(idx, 128, 128, 255)
                else:
                    offset = layerIdx * linearSize
                    imageIdx = idx % linearSize
                    vect = normalByLayer.GetTuple3(imageIdx + offset)
                    if (not math.isnan(vect[0]) and not math.isnan(vect[1])
                            and not math.isnan(vect[2])):
                        sortedNormal.SetTuple3(
                            idx,
                            int(127.5 * (vect[0] + 1)),
                            int(127.5 * (vect[1] + 1)),
                            int(255 * vect[2]),
                        )
                    else:
                        print(
                            "WARNING: encountered NaN in normal of layer ",
                            layerIdx,
                            ": [",
                            vect[0],
                            ",",
                            vect[1],
                            ",",
                            vect[2],
                            "]",
                        )
                        sortedNormal.SetTuple3(idx, 128, 128, 255)

            # Write the sorted data
            with open(os.path.join(directory, "normal.uint8"), "wb") as f:
                f.write(memoryview(sortedNormal))
                self.data.append({
                    "name": "normal",
                    "type": "array",
                    "fileName": "/normal.uint8",
                    "categories": ["normal"],
                })

            # Remove depth files
            for layerIdx in layerList:
                os.remove(
                    os.path.join(directory,
                                 "normal_%d_%d.float32" % (layerIdx, 0)))
                os.remove(
                    os.path.join(directory,
                                 "normal_%d_%d.float32" % (layerIdx, 1)))
                os.remove(
                    os.path.join(directory,
                                 "normal_%d_%d.float32" % (layerIdx, 2)))

        # Encode Intensity (sorted order way)
        if "intensity" in self.config["light"]:
            sortedIntensity = vtkUnsignedCharArray()
            sortedIntensity.SetNumberOfTuples(stackSize)

            intensityLayers = []
            for layerIdx in layerList:
                with open(
                        os.path.join(directory,
                                     "intensity_%d.uint8" % layerIdx),
                        "rb") as f:
                    a = array.array("B")
                    a.fromfile(f, linearSize)
                    intensityLayers.append(a)

            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    sortedIntensity.SetValue(idx, 255)
                else:
                    imageIdx = idx % linearSize
                    sortedIntensity.SetValue(
                        idx, intensityLayers[layerIdx][imageIdx])

            with open(os.path.join(directory, "intensity.uint8"), "wb") as f:
                f.write(memoryview(sortedIntensity))
                self.data.append({
                    "name": "intensity",
                    "type": "array",
                    "fileName": "/intensity.uint8",
                    "categories": ["intensity"],
                })

            # Remove depth files
            for layerIdx in layerList:
                os.remove(
                    os.path.join(directory, "intensity_%d.uint8" % layerIdx))
Exemplo n.º 12
0
    def processDirectory(self, directory):
        self.imageReader.SetFileName(os.path.join(directory, "rgb.png"))
        self.imageReader.Update()
        rgbArray = self.imageReader.GetOutput().GetPointData().GetArray(0)

        self.composite.load(os.path.join(directory, "composite.json"))
        orderArray = self.composite.getSortedOrderArray()

        imageSize = self.composite.getImageSize()
        stackSize = self.composite.getStackSize()

        # Write order (sorted order way)
        with open(os.path.join(directory, "order.uint8"), "wb") as f:
            f.write(memoryview(orderArray))
            self.data.append({
                "name": "order",
                "type": "array",
                "fileName": "/order.uint8"
            })

        # Encode Normals (sorted order way)
        if "normal" in self.layers[0]:
            sortedNormal = vtkUnsignedCharArray()
            sortedNormal.SetNumberOfComponents(3)  # x,y,z
            sortedNormal.SetNumberOfTuples(stackSize)

            # Get Camera orientation and rotation information
            camDir = [0, 0, 0]
            worldUp = [0, 0, 0]
            with open(os.path.join(directory, "camera.json"), "r") as f:
                camera = json.load(f)
                camDir = normalize([
                    camera["position"][i] - camera["focalPoint"][i]
                    for i in range(3)
                ])
                worldUp = normalize(camera["viewUp"])

            # [ camRight, camUp, camDir ] will be our new orthonormal basis for normals
            camRight = vectProduct(camDir, worldUp)
            camUp = vectProduct(camRight, camDir)

            # Tmp structure to capture (x,y,z) normal
            normalByLayer = vtkFloatArray()
            normalByLayer.SetNumberOfComponents(3)
            normalByLayer.SetNumberOfTuples(stackSize)

            # Capture all layer normals
            layerIdx = 0
            zPosCount = 0
            zNegCount = 0
            for layer in self.layers:
                normalOffset = layer["normal"]
                for idx in range(imageSize):
                    normalByLayer.SetTuple3(
                        layerIdx * imageSize + idx,
                        getScalarFromRGB(
                            rgbArray.GetTuple(idx +
                                              normalOffset[0] * imageSize)),
                        getScalarFromRGB(
                            rgbArray.GetTuple(idx +
                                              normalOffset[1] * imageSize)),
                        getScalarFromRGB(
                            rgbArray.GetTuple(idx +
                                              normalOffset[2] * imageSize)),
                    )

                    # Re-orient normal to be view based
                    vect = normalByLayer.GetTuple3(layerIdx * imageSize + idx)
                    if not math.isnan(vect[0]):
                        # Express normal in new basis we computed above
                        rVect = normalize([
                            -dotProduct(vect, camRight),
                            dotProduct(vect, camUp),
                            dotProduct(vect, camDir),
                        ])

                        # Need to reverse vector ?
                        if rVect[2] < 0:
                            normalByLayer.SetTuple3(
                                layerIdx * imageSize + idx,
                                -rVect[0],
                                -rVect[1],
                                -rVect[2],
                            )
                        else:
                            normalByLayer.SetTuple3(layerIdx * imageSize + idx,
                                                    rVect[0], rVect[1],
                                                    rVect[2])

                layerIdx += 1

            # Sort normals and encode them as 3 bytes ( -1 < xy < 1 | 0 < z < 1)
            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    # No normal => same as view direction
                    sortedNormal.SetTuple3(idx, 128, 128, 255)
                else:
                    offset = layerIdx * imageSize
                    imageIdx = idx % imageSize
                    vect = normalByLayer.GetTuple3(imageIdx + offset)
                    if (not math.isnan(vect[0]) and not math.isnan(vect[1])
                            and not math.isnan(vect[2])):
                        sortedNormal.SetTuple3(
                            idx,
                            int(127.5 * (vect[0] + 1)),
                            int(127.5 * (vect[1] + 1)),
                            int(255 * vect[2]),
                        )
                    else:
                        print(
                            "WARNING: encountered NaN in normal of layer ",
                            layerIdx,
                            ": [",
                            vect[0],
                            ",",
                            vect[1],
                            ",",
                            vect[2],
                            "]",
                        )
                        sortedNormal.SetTuple3(idx, 128, 128, 255)

            # Write the sorted data
            with open(os.path.join(directory, "normal.uint8"), "wb") as f:
                f.write(memoryview(sortedNormal))
                self.data.append({
                    "name": "normal",
                    "type": "array",
                    "fileName": "/normal.uint8",
                    "categories": ["normal"],
                })

        # Encode Intensity (sorted order way)
        if "intensity" in self.layers[0]:
            intensityOffsets = []
            sortedIntensity = vtkUnsignedCharArray()
            sortedIntensity.SetNumberOfTuples(stackSize)

            for layer in self.layers:
                intensityOffsets.append(layer["intensity"])

            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    sortedIntensity.SetValue(idx, 255)
                else:
                    offset = 3 * intensityOffsets[layerIdx] * imageSize
                    imageIdx = idx % imageSize
                    sortedIntensity.SetValue(
                        idx, rgbArray.GetValue(imageIdx * 3 + offset))

            with open(os.path.join(directory, "intensity.uint8"), "wb") as f:
                f.write(memoryview(sortedIntensity))
                self.data.append({
                    "name": "intensity",
                    "type": "array",
                    "fileName": "/intensity.uint8",
                    "categories": ["intensity"],
                })

        # Encode Each layer Scalar
        layerIdx = 0
        for layer in self.layers:
            for scalar in layer:
                if scalar not in ["intensity", "normal"]:
                    offset = imageSize * layer[scalar]
                    scalarRange = self.config["scene"][layerIdx]["colors"][
                        scalar]["range"]
                    delta = (scalarRange[1] - scalarRange[0]
                             ) / 16777215.0  # 2^24 - 1 => 16,777,215

                    scalarArray = vtkFloatArray()
                    scalarArray.SetNumberOfTuples(imageSize)
                    for idx in range(imageSize):
                        rgb = rgbArray.GetTuple(idx + offset)
                        if rgb[0] != 0 or rgb[1] != 0 or rgb[2] != 0:
                            # Decode encoded value
                            value = scalarRange[0] + delta * float(
                                rgb[0] * 65536 + rgb[1] * 256 + rgb[2] - 1)
                            scalarArray.SetValue(idx, value)
                        else:
                            # No value
                            scalarArray.SetValue(idx, float("NaN"))

                    with open(
                            os.path.join(directory,
                                         "%d_%s.float32" % (layerIdx, scalar)),
                            "wb",
                    ) as f:
                        f.write(memoryview(scalarArray))
                        self.data.append({
                            "name":
                            "%d_%s" % (layerIdx, scalar),
                            "type":
                            "array",
                            "fileName":
                            "/%d_%s.float32" % (layerIdx, scalar),
                            "categories": ["%d_%s" % (layerIdx, scalar)],
                        })

            layerIdx += 1
Exemplo n.º 13
0
    def testHypterTreeGridMask(self):
        "Test a simple hyper tree grid with masking"

        htg = vtkHyperTreeGrid()

        scalarArray = vtkUnsignedCharArray()
        scalarArray.SetName('scalar')
        scalarArray.SetNumberOfValues(0)

        mask = vtkBitArray()
        mask.SetName('mask')
        mask.SetNumberOfValues(22)
        mask.FillComponent(0, 0)
        htg.SetMaterialMask(mask)

        htg.GetPointData().SetScalars(scalarArray)

        htg.Initialize()
        htg.SetGridSize([3, 2, 1])
        htg.SetDimension(2)
        htg.SetBranchFactor(2)
        # specify normal index to ignore
        htg.SetOrientation(2)
        # htg.SetTransposedRootIndexing(False)

        # rectilinear grid coordinates
        xValues = vtkDoubleArray()
        xValues.SetNumberOfValues(4)
        xValues.SetValue(0, -1)
        xValues.SetValue(1, 0)
        xValues.SetValue(2, 1)
        xValues.SetValue(3, 2)
        htg.SetXCoordinates(xValues);

        yValues = vtkDoubleArray()
        yValues.SetNumberOfValues(3)
        yValues.SetValue(0, -1)
        yValues.SetValue(1, 0)
        yValues.SetValue(2, 1)
        htg.SetYCoordinates(yValues);

        zValues = vtkDoubleArray()
        zValues.SetNumberOfValues(1)
        zValues.SetValue(0, 0)
        htg.SetZCoordinates(zValues);

        # Let's split the various trees
        cursor = vtkHyperTreeGridNonOrientedCursor()
        offsetIndex = 0

        # ROOT CELL 0
        htg.InitializeNonOrientedCursor(cursor, 0, True)
        cursor.SetGlobalIndexStart(offsetIndex)

        # coarse value
        idx = cursor.GetGlobalNodeIndex()

        # GLOBAL...
        # cursor.SetGlobalIndexFromLocal(idx)

        scalarArray.InsertTuple1(idx, 0)

        # ROOT CELL 0/[0-3]
        cursor.SubdivideLeaf()
        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 24)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 27)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 18)
        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 21)
        cursor.ToParent()

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 1
        htg.InitializeNonOrientedCursor(cursor, 1, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 15)

        # Mask
        mask.SetValue(idx, 1)

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 2
        htg.InitializeNonOrientedCursor(cursor, 2, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 2)

        # Mask
        mask.SetValue(idx, 1)

        # ROOT CELL 2/[0-3]
        cursor.SubdivideLeaf()
        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 36)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 39)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 30)

        # Mask
        mask.SetValue(idx, 1)

        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 33)
        cursor.ToParent()

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 3
        htg.InitializeNonOrientedCursor(cursor, 3, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 0)

        offsetIndex += cursor.GetTree().GetNumberOfVertices()

        # ROOT CELL 4
        htg.InitializeNonOrientedCursor(cursor, 4, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 4)

        # ROOT CELL 4/[0-3]
        cursor.SubdivideLeaf()
        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 9)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 12)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 3)
        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 51)
        cursor.ToParent()

        # ROOT CELL 4/3/[0-3]
        cursor.ToChild(3)
        cursor.SubdivideLeaf()

        cursor.ToChild(0)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 45)
        cursor.ToParent()

        cursor.ToChild(1)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 51)
        cursor.ToParent()

        cursor.ToChild(2)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 6)
        # Mask
        mask.SetValue(idx, 1)
        cursor.ToParent()

        cursor.ToChild(3)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 45)
        cursor.ToParent()

        offsetIndex += cursor.GetTree().GetNumberOfVertices()


        # ROOT CELL 5
        htg.InitializeNonOrientedCursor(cursor, 5, True)
        cursor.SetGlobalIndexStart(offsetIndex)
        idx = cursor.GetGlobalNodeIndex()
        scalarArray.InsertTuple1(idx, 42)

        # ---------------------------------------------------------------------
        # Convert HTG to PolyData
        # ---------------------------------------------------------------------

        geometryFilter = vtkHyperTreeGridGeometry()
        geometryFilter.SetInputData(htg)

        # ---------------------------------------------------------------------
        # Rendering
        # ---------------------------------------------------------------------

        ren1 = vtk.vtkRenderer()
        renWin = vtk.vtkRenderWindow()
        renWin.AddRenderer(ren1)
        iren = vtk.vtkRenderWindowInteractor()
        iren.SetRenderWindow(renWin)

        lut = vtk.vtkLookupTable()
        lut.SetHueRange(0.66, 0)
        lut.SetSaturationRange(1.0, 0.25);
        lut.SetTableRange(0, 51)
        lut.Build()

        mapper = vtk.vtkDataSetMapper()
        mapper.SetLookupTable(lut)
        mapper.SetColorModeToMapScalars()
        mapper.SetScalarModeToUseCellFieldData()
        mapper.SelectColorArray('scalar')
        mapper.SetInputConnection(geometryFilter.GetOutputPort())
        mapper.UseLookupTableScalarRangeOn()
        mapper.SetScalarRange(0, 51);

        actor = vtk.vtkActor()
        actor.SetMapper(mapper)

        ren1.AddActor(actor)
        renWin.SetSize(350,350)
        ren1.SetBackground(0.5,0.5,0.5)
        ren1.ResetCamera()
        renWin.Render()

        img_file = "TestHyperTreeGridMask.png"
        vtk.test.Testing.compareImage(renWin, vtk.test.Testing.getAbsImagePath(img_file), threshold=25)
        vtk.test.Testing.interact()
Exemplo n.º 14
0
    def writeData(self):
        composite_size = len(self.representations)

        self.view.UpdatePropertyInformation()
        self.view.Background = [0,0,0]
        imageSize = self.view.ViewSize[0] * self.view.ViewSize[1]

        # Generate the heavy data
        for camPos in self.getCamera():
            self.view.CameraFocalPoint = camPos['focalPoint']
            self.view.CameraPosition = camPos['position']
            self.view.CameraViewUp = camPos['viewUp']

            # Show all representations
            for compositeIdx in range(composite_size):
                rep = self.representations[compositeIdx]
                rep.Visibility = 1

            # Fix camera bounds
            self.view.LockBounds = 0
            simple.Render(self.view)
            self.view.LockBounds = 1

            # Update destination directory
            dest_path = os.path.dirname(self.dataHandler.getDataAbsoluteFilePath('directory'))

            # Write camera information
            if self.dataHandler.can_write:
                with open(os.path.join(dest_path, "camera.json"), 'w') as f:
                    f.write(json.dumps(camPos))

            # Hide all representations
            for compositeIdx in range(composite_size):
                rep = self.representations[compositeIdx]
                rep.Visibility = 0

            # Show only active Representation
            # Extract images for each fields
            for compositeIdx in range(composite_size):
                rep = self.representations[compositeIdx]
                if compositeIdx > 0:
                    self.representations[compositeIdx - 1].Visibility = 0
                rep.Visibility = 1

                # capture Z
                simple.Render()
                zBuffer = self.view.CaptureDepthBuffer()
                with open(os.path.join(dest_path, 'depth_%d.float32' % compositeIdx), 'wb') as f:
                    f.write(buffer(zBuffer))

                # Prevent color interference
                rep.DiffuseColor = [1,1,1]

                # Handle light
                for lightType in self.config['light']:
                    if lightType == 'intensity':
                        rep.AmbientColor  = [1,1,1]
                        rep.SpecularColor = [1,1,1]

                        self.view.StartCaptureLuminance()
                        image = self.view.CaptureWindow(1)
                        imagescalars = image.GetPointData().GetScalars()
                        self.view.StopCaptureLuminance()

                        # Extract specular information
                        specularOffset = 1 # [diffuse, specular, ?]
                        imageSize = imagescalars.GetNumberOfTuples()
                        specularComponent = vtkUnsignedCharArray()
                        specularComponent.SetNumberOfComponents(1)
                        specularComponent.SetNumberOfTuples(imageSize)

                        for idx in range(imageSize):
                            specularComponent.SetValue(idx, imagescalars.GetValue(idx * 3 + specularOffset))

                        with open(os.path.join(dest_path, 'intensity_%d.uint8' % compositeIdx), 'wb') as f:
                            f.write(buffer(specularComponent))

                        # Free memory
                        image.UnRegister(None)

                    if lightType == 'normal':
                        if rep.Representation in ['Point Gaussian', 'Points', 'Outline', 'Wireframe']:
                            uniqNormal = [(camPos['position'][i] - camPos['focalPoint'][i]) for i in range(3)]
                            tmpNormalArray = vtkFloatArray()
                            tmpNormalArray.SetNumberOfComponents(1)
                            tmpNormalArray.SetNumberOfTuples(imageSize)

                            for comp in range(3):
                                tmpNormalArray.FillComponent(0, uniqNormal[comp])
                                with open(os.path.join(dest_path, 'normal_%d_%d.float32' % (compositeIdx, comp)), 'wb') as f:
                                    f.write(buffer(tmpNormalArray))
                        else:
                            for comp in range(3):
                                # Configure view to handle POINT_DATA / CELL_DATA
                                self.view.DrawCells = 0
                                self.view.ArrayNameToDraw = 'Normals'
                                self.view.ArrayComponentToDraw = comp
                                self.view.ScalarRange = [-1.0, 1.0]
                                self.view.StartCaptureValues()
                                image = self.view.CaptureWindow(1)
                                imagescalars = image.GetPointData().GetScalars()
                                self.view.StopCaptureValues()

                                # Convert RGB => Float => Write
                                floatArray = data_converter.convertRGBArrayToFloatArray(imagescalars, [-1.0, 1.0])
                                with open(os.path.join(dest_path, 'normal_%d_%d.float32' % (compositeIdx, comp)), 'wb') as f:
                                    f.write(buffer(floatArray))

                                # Free memory
                                image.UnRegister(None)

                # Handle color by
                for fieldName, fieldConfig in iteritems(self.config['scene'][compositeIdx]['colors']):
                    if 'constant' in fieldConfig:
                        # Skip nothing to render
                        continue

                    # Configure view to handle POINT_DATA / CELL_DATA
                    if fieldConfig['location'] == 'POINT_DATA':
                        self.view.DrawCells = 0
                    else:
                        self.view.DrawCells = 1

                    self.view.ArrayNameToDraw = fieldName
                    self.view.ArrayComponentToDraw = 0
                    self.view.ScalarRange = fieldConfig['range']
                    self.view.StartCaptureValues()
                    image = self.view.CaptureWindow(1)
                    imagescalars = image.GetPointData().GetScalars()
                    self.view.StopCaptureValues()

                    floatArray = data_converter.convertRGBArrayToFloatArray(imagescalars, fieldConfig['range'])
                    with open(os.path.join(dest_path, '%d_%s.float32' % (compositeIdx, fieldName)), 'wb') as f:
                        f.write(buffer(floatArray))
                        self.dataHandler.registerData(name='%d_%s' % (compositeIdx, fieldName), fileName='/%d_%s.float32' % (compositeIdx, fieldName), type='array', categories=['%d_%s' % (compositeIdx, fieldName)])

                    # Free memory
                    image.UnRegister(None)
Exemplo n.º 15
0
    def processDirectory(self, directory):
        # Load depth
        depthStack = []
        imageSize = self.config['size']
        linearSize = imageSize[0] * imageSize[1]
        nbLayers = len(self.layers)
        stackSize = nbLayers * linearSize
        layerList = range(nbLayers)
        for layerIdx in layerList:
            with open(os.path.join(directory, 'depth_%d.float32' % layerIdx), "rb") as f:
                a = array.array('f')
                a.fromfile(f, linearSize)
                depthStack.append(a)

        orderArray = vtkUnsignedCharArray()
        orderArray.SetName('layerIdx');
        orderArray.SetNumberOfComponents(1)
        orderArray.SetNumberOfTuples(stackSize)

        pixelSorter = [(i, i) for i in layerList]

        for pixelId in range(linearSize):
            # Fill pixelSorter
            for layerIdx in layerList:
                if depthStack[layerIdx][pixelId] < 1.0:
                    pixelSorter[layerIdx] = (layerIdx, depthStack[layerIdx][pixelId])
                else:
                    pixelSorter[layerIdx] = (255, 1.0)

            # Sort pixel layers
            pixelSorter.sort(key=lambda tup: tup[1])

            # Fill sortedOrder array
            for layerIdx in layerList:
                orderArray.SetValue(layerIdx * linearSize + pixelId, pixelSorter[layerIdx][0])

        # Write order (sorted order way)
        with open(os.path.join(directory, 'order.uint8'), 'wb') as f:
            f.write(buffer(orderArray))
            self.data.append({'name': 'order', 'type': 'array', 'fileName': '/order.uint8'})

        # Remove depth files
        for layerIdx in layerList:
            os.remove(os.path.join(directory, 'depth_%d.float32' % layerIdx))


        # Encode Normals (sorted order way)
        if 'normal' in self.config['light']:
            sortedNormal = vtkUnsignedCharArray()
            sortedNormal.SetNumberOfComponents(3) # x,y,z
            sortedNormal.SetNumberOfTuples(stackSize)

            # Get Camera orientation and rotation information
            camDir = [0,0,0]
            worldUp = [0,0,0]
            with open(os.path.join(directory, "camera.json"), "r") as f:
                camera = json.load(f)
                camDir = normalize([ camera['position'][i] - camera['focalPoint'][i] for i in range(3) ])
                worldUp = normalize(camera['viewUp'])

            # [ camRight, camUp, camDir ] will be our new orthonormal basis for normals
            camRight = vectProduct(camDir, worldUp)
            camUp = vectProduct(camRight, camDir)

            # Tmp structure to capture (x,y,z) normal
            normalByLayer = vtkFloatArray()
            normalByLayer.SetNumberOfComponents(3)
            normalByLayer.SetNumberOfTuples(stackSize)

            # Capture all layer normals
            zPosCount = 0
            zNegCount = 0
            for layerIdx in layerList:

                # Load normal(x,y,z) from current layer
                normalLayer = []
                for comp in [0, 1, 2]:
                    with open(os.path.join(directory, 'normal_%d_%d.float32' % (layerIdx, comp)), "rb") as f:
                        a = array.array('f')
                        a.fromfile(f, linearSize)
                        normalLayer.append(a)

                # Store normal inside vtkArray
                offset = layerIdx * linearSize
                for idx in range(linearSize):
                    normalByLayer.SetTuple3(
                        idx + offset,
                        normalLayer[0][idx],
                        normalLayer[1][idx],
                        normalLayer[2][idx]
                    )

                    # Re-orient normal to be view based
                    vect = normalByLayer.GetTuple3(layerIdx * linearSize + idx)
                    if not math.isnan(vect[0]):
                        # Express normal in new basis we computed above
                        rVect = normalize([ -dotProduct(vect, camRight), dotProduct(vect, camUp), dotProduct(vect, camDir)  ])

                        # Need to reverse vector ?
                        if rVect[2] < 0:
                            normalByLayer.SetTuple3(layerIdx * linearSize + idx, -rVect[0], -rVect[1], -rVect[2])
                        else:
                            normalByLayer.SetTuple3(layerIdx * linearSize + idx, rVect[0], rVect[1], rVect[2])

            # Sort normals and encode them as 3 bytes ( -1 < xy < 1 | 0 < z < 1)
            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    # No normal => same as view direction
                    sortedNormal.SetTuple3(idx, 128, 128, 255)
                else:
                    offset = layerIdx * linearSize
                    imageIdx = idx % linearSize
                    vect = normalByLayer.GetTuple3(imageIdx + offset)
                    if not math.isnan(vect[0]) and not math.isnan(vect[1]) and not math.isnan(vect[2]):
                        sortedNormal.SetTuple3(idx, int(127.5 * (vect[0] + 1)), int(127.5 * (vect[1] + 1)), int(255 * vect[2]))
                    else:
                        print ('WARNING: encountered NaN in normal of layer ',layerIdx,': [',vect[0],',',vect[1],',',vect[2],']')
                        sortedNormal.SetTuple3(idx, 128, 128, 255)

            # Write the sorted data
            with open(os.path.join(directory, 'normal.uint8'), 'wb') as f:
                f.write(buffer(sortedNormal))
                self.data.append({'name': 'normal', 'type': 'array', 'fileName': '/normal.uint8', 'categories': ['normal']})

            # Remove depth files
            for layerIdx in layerList:
                os.remove(os.path.join(directory, 'normal_%d_%d.float32' % (layerIdx, 0)))
                os.remove(os.path.join(directory, 'normal_%d_%d.float32' % (layerIdx, 1)))
                os.remove(os.path.join(directory, 'normal_%d_%d.float32' % (layerIdx, 2)))

        # Encode Intensity (sorted order way)
        if 'intensity' in self.config['light']:
            sortedIntensity = vtkUnsignedCharArray()
            sortedIntensity.SetNumberOfTuples(stackSize)

            intensityLayers = []
            for layerIdx in layerList:
                with open(os.path.join(directory, 'intensity_%d.uint8' % layerIdx), "rb") as f:
                    a = array.array('B')
                    a.fromfile(f, linearSize)
                    intensityLayers.append(a)

            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    sortedIntensity.SetValue(idx, 255)
                else:
                    imageIdx = idx % linearSize
                    sortedIntensity.SetValue(idx, intensityLayers[layerIdx][imageIdx])

            with open(os.path.join(directory, 'intensity.uint8'), 'wb') as f:
                f.write(buffer(sortedIntensity))
                self.data.append({'name': 'intensity', 'type': 'array', 'fileName': '/intensity.uint8', 'categories': ['intensity']})

            # Remove depth files
            for layerIdx in layerList:
                os.remove(os.path.join(directory, 'intensity_%d.uint8' % layerIdx))
Exemplo n.º 16
0
    def processDirectory(self, directory):
        self.imageReader.SetFileName(os.path.join(directory, 'rgb.png'))
        self.imageReader.Update()
        rgbArray = self.imageReader.GetOutput().GetPointData().GetArray(0)

        self.composite.load(os.path.join(directory, 'composite.json'))
        orderArray = self.composite.getSortedOrderArray()

        imageSize = self.composite.getImageSize()
        stackSize = self.composite.getStackSize()

        # Write order (sorted order way)
        with open(os.path.join(directory, 'order.uint8'), 'wb') as f:
            f.write(buffer(orderArray))
            self.data.append({'name': 'order', 'type': 'array', 'fileName': '/order.uint8'})

        # Encode Normals (sorted order way)
        if 'normal' in self.layers[0]:
            sortedNormal = vtkUnsignedCharArray()
            sortedNormal.SetNumberOfComponents(3) # x,y,z
            sortedNormal.SetNumberOfTuples(stackSize)

            # Get Camera orientation and rotation information
            camDir = [0,0,0]
            worldUp = [0,0,0]
            with open(os.path.join(directory, "camera.json"), "r") as f:
                camera = json.load(f)
                camDir = normalize([ camera['position'][i] - camera['focalPoint'][i] for i in range(3) ])
                worldUp = normalize(camera['viewUp'])

            # [ camRight, camUp, camDir ] will be our new orthonormal basis for normals
            camRight = vectProduct(camDir, worldUp)
            camUp = vectProduct(camRight, camDir)

            # Tmp structure to capture (x,y,z) normal
            normalByLayer = vtkFloatArray()
            normalByLayer.SetNumberOfComponents(3)
            normalByLayer.SetNumberOfTuples(stackSize)

            # Capture all layer normals
            layerIdx = 0
            zPosCount = 0
            zNegCount = 0
            for layer in self.layers:
                normalOffset = layer['normal']
                for idx in range(imageSize):
                    normalByLayer.SetTuple3(
                        layerIdx * imageSize + idx,
                        getScalarFromRGB(rgbArray.GetTuple(idx + normalOffset[0] * imageSize)),
                        getScalarFromRGB(rgbArray.GetTuple(idx + normalOffset[1] * imageSize)),
                        getScalarFromRGB(rgbArray.GetTuple(idx + normalOffset[2] * imageSize))
                    )

                    # Re-orient normal to be view based
                    vect = normalByLayer.GetTuple3(layerIdx * imageSize + idx)
                    if not math.isnan(vect[0]):
                        # Express normal in new basis we computed above
                        rVect = normalize([ -dotProduct(vect, camRight), dotProduct(vect, camUp), dotProduct(vect, camDir)  ])

                        # Need to reverse vector ?
                        if rVect[2] < 0:
                            normalByLayer.SetTuple3(layerIdx * imageSize + idx, -rVect[0], -rVect[1], -rVect[2])
                        else:
                            normalByLayer.SetTuple3(layerIdx * imageSize + idx, rVect[0], rVect[1], rVect[2])

                layerIdx += 1

            # Sort normals and encode them as 3 bytes ( -1 < xy < 1 | 0 < z < 1)
            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    # No normal => same as view direction
                    sortedNormal.SetTuple3(idx, 128, 128, 255)
                else:
                    offset = layerIdx * imageSize
                    imageIdx = idx % imageSize
                    vect = normalByLayer.GetTuple3(imageIdx + offset)
                    if not math.isnan(vect[0]) and not math.isnan(vect[1]) and not math.isnan(vect[2]):
                        sortedNormal.SetTuple3(idx, int(127.5 * (vect[0] + 1)), int(127.5 * (vect[1] + 1)), int(255 * vect[2]))
                    else:
                        print ('WARNING: encountered NaN in normal of layer ',layerIdx,': [',vect[0],',',vect[1],',',vect[2],']')
                        sortedNormal.SetTuple3(idx, 128, 128, 255)

            # Write the sorted data
            with open(os.path.join(directory, 'normal.uint8'), 'wb') as f:
                f.write(buffer(sortedNormal))
                self.data.append({'name': 'normal', 'type': 'array', 'fileName': '/normal.uint8', 'categories': ['normal']})

        # Encode Intensity (sorted order way)
        if 'intensity' in self.layers[0]:
            intensityOffsets = []
            sortedIntensity = vtkUnsignedCharArray()
            sortedIntensity.SetNumberOfTuples(stackSize)

            for layer in self.layers:
                intensityOffsets.append(layer['intensity'])

            for idx in range(stackSize):
                layerIdx = int(orderArray.GetValue(idx))
                if layerIdx == 255:
                    sortedIntensity.SetValue(idx, 255)
                else:
                    offset = 3 * intensityOffsets[layerIdx] * imageSize
                    imageIdx = idx % imageSize
                    sortedIntensity.SetValue(idx, rgbArray.GetValue(imageIdx * 3 + offset))

            with open(os.path.join(directory, 'intensity.uint8'), 'wb') as f:
                f.write(buffer(sortedIntensity))
                self.data.append({'name': 'intensity', 'type': 'array', 'fileName': '/intensity.uint8', 'categories': ['intensity']})

        # Encode Each layer Scalar
        layerIdx = 0
        for layer in self.layers:
            for scalar in layer:
                if scalar not in ['intensity', 'normal']:
                    offset = imageSize * layer[scalar]
                    scalarRange = self.config['scene'][layerIdx]['colors'][scalar]['range']
                    delta = (scalarRange[1] - scalarRange[0]) / 16777215.0 # 2^24 - 1 => 16,777,215

                    scalarArray = vtkFloatArray()
                    scalarArray.SetNumberOfTuples(imageSize)
                    for idx in range(imageSize):
                        rgb = rgbArray.GetTuple(idx + offset)
                        if rgb[0] != 0 or rgb[1] != 0 or rgb[2] != 0:
                            # Decode encoded value
                            value = scalarRange[0] + delta * float(rgb[0]*65536 + rgb[1]*256 + rgb[2] - 1)
                            scalarArray.SetValue(idx, value)
                        else:
                            # No value
                            scalarArray.SetValue(idx, float('NaN'))


                    with open(os.path.join(directory, '%d_%s.float32' % (layerIdx, scalar)), 'wb') as f:
                        f.write(buffer(scalarArray))
                        self.data.append({'name': '%d_%s' % (layerIdx, scalar), 'type': 'array', 'fileName': '/%d_%s.float32' % (layerIdx, scalar), 'categories': ['%d_%s' % (layerIdx, scalar)]})

            layerIdx += 1