예제 #1
0
def convertRGBArrayToFloatArray(rgbArray, scalarRange=[0.0, 1.0]):
    linearSize = rgbArray.GetNumberOfTuples()

    outputArray = vtkFloatArray()
    outputArray.SetNumberOfComponents(1)
    outputArray.SetNumberOfTuples(linearSize)

    for idx in range(linearSize):
        outputArray.SetTuple1(
            idx, getScalarFromRGB(rgbArray.GetTuple(idx), scalarRange))

    return outputArray
예제 #2
0
def convertRGBArrayToFloatArray(rgbArray, scalarRange=[0.0, 1.0]):
    linearSize = rgbArray.GetNumberOfTuples()

    outputArray = vtkFloatArray()
    outputArray.SetNumberOfComponents(1)
    outputArray.SetNumberOfTuples(linearSize)

    for idx in range(linearSize):
        outputArray.SetTuple1(
            idx,
            getScalarFromRGB(rgbArray.GetTuple(idx), scalarRange)
        )

    return outputArray
예제 #3
0
def transform_scalars(dataset, label_value=1):
    """Computes the principal axes of an object with the label value passed in
    as the parameter label_value. The principal axes are added to the field
    data of the dataset as an array of 3-component tuples named 'PrincipalAxes'.
    The principal axis tuples are stored in order of length from longest to
    shortest. The center of the object is also added to the field data as an
    array named 'Center' with a single 3-component tuple.

    This operator uses principal components analysis of the labeled point
    locations to determine the principal axes.
    """

    from tomviz import utils
    from vtkmodules.vtkCommonCore import vtkFloatArray

    fd = dataset.GetFieldData()

    (axes, center) = utils.label_object_principal_axes(dataset, label_value)
    print(axes)
    print(center)
    axis_array = vtkFloatArray()
    axis_array.SetName('PrincipalAxes')
    axis_array.SetNumberOfComponents(3)
    axis_array.SetNumberOfTuples(3)
    axis_array.InsertTypedTuple(0, list(axes[:, 0]))
    axis_array.InsertTypedTuple(1, list(axes[:, 1]))
    axis_array.InsertTypedTuple(2, list(axes[:, 2]))
    fd.RemoveArray('PrincipalAxis')
    fd.AddArray(axis_array)

    center_array = vtkFloatArray()
    center_array.SetName('Center')
    center_array.SetNumberOfComponents(3)
    center_array.SetNumberOfTuples(1)
    center_array.InsertTypedTuple(0, list(center))
    fd.RemoveArray('Center')
    fd.AddArray(center_array)
예제 #4
0
def convertImageToFloat(srcPngImage, destFile, scalarRange=[0.0, 1.0]):
    reader = vtkPNGReader()
    reader.SetFileName(srcPngImage)
    reader.Update()
    rgbArray = reader.GetOutput().GetPointData().GetArray(0)
    stackSize = rgbArray.GetNumberOfTuples()
    size = reader.GetOutput().GetDimensions()

    outputArray = vtkFloatArray()
    outputArray.SetNumberOfComponents(1)
    outputArray.SetNumberOfTuples(stackSize)

    for idx in range(stackSize):
        outputArray.SetTuple1(
            idx, getScalarFromRGB(rgbArray.GetTuple(idx), scalarRange))

    # Write float file
    with open(destFile, "wb") as f:
        f.write(memoryview(outputArray))

    return size
예제 #5
0
def convertImageToFloat(srcPngImage, destFile, scalarRange=[0.0, 1.0]):
    reader = vtkPNGReader()
    reader.SetFileName(srcPngImage)
    reader.Update()
    rgbArray = reader.GetOutput().GetPointData().GetArray(0)
    stackSize = rgbArray.GetNumberOfTuples()
    size = reader.GetOutput().GetDimensions()


    outputArray = vtkFloatArray()
    outputArray.SetNumberOfComponents(1)
    outputArray.SetNumberOfTuples(stackSize)

    for idx in range(stackSize):
        outputArray.SetTuple1(
            idx,
            getScalarFromRGB(rgbArray.GetTuple(idx), scalarRange)
        )

    # Write float file
    with open(destFile, 'wb') as f:
        f.write(buffer(outputArray))

    return size
예제 #6
0
    def RequestData(self, request, inInfoVec, outInfoVec):
        from vtkmodules.vtkCommonCore import vtkFloatArray, vtkPoints
        from vtkmodules.vtkCommonDataModel import (
            vtkCellArray, vtkCompositeDataSet, vtkPartitionedDataSet,
            vtkPartitionedDataSetCollection, vtkPolyData)

        output = vtkPartitionedDataSetCollection.GetData(outInfoVec)
        partitioned_datasets = []
        partitioned_dataset_names = []

        # Parse line file
        if not self._filename:
            print_error("SAVGReader requires a FileName")
            return 0

        # Stores lines of text from the file associated with each group of
        # geometries encountered.
        geometries = {"lines": [], "points": [], "poly": []}

        # Read the file and build up data structure to hold the primitives
        with open(self._filename, "r") as file:
            current = None
            for line in file:
                parts = line.split("#")
                line = parts[0].strip().lower()

                if len(line) < 1:
                    continue

                if not_supported(line):
                    continue

                if line.startswith("lin"):
                    geometries["lines"].append({"rgba": None, "values": []})
                    current = geometries["lines"][-1]
                    line_parts = line.split(" ")
                    if len(line_parts) == 5:
                        current["rgba"] = [float(n) for n in line_parts[1:]]
                elif line.startswith("point"):
                    geometries["points"].append({
                        "rgba": None,
                        "values": [],
                    })
                    current = geometries["points"][-1]
                    line_parts = line.split(" ")
                    if len(line_parts) == 5:
                        current["rgba"] = [float(n) for n in line_parts[1:]]
                elif line.startswith("poly"):
                    geometries["poly"].append({
                        "rgba": None,
                        "npts": None,
                        "values": [],
                    })
                    current = geometries["poly"][-1]
                    line_parts = line.split(" ")
                    if len(line_parts) == 2:
                        current["npts"] = int(line_parts[1])
                    elif len(line_parts) == 6:
                        current["rgba"] = [float(n) for n in line_parts[1:5]]
                        current["npts"] = int(line_parts[5])
                elif line.startswith("end"):
                    current = None
                else:
                    if current is not None:
                        if "npts" in current and current["npts"] is not None:
                            # polygon, known num pts per poly
                            if len(current["values"]) == current["npts"]:
                                # Reached the number of points for the current one,
                                # start a new one.
                                geometries["poly"].append({
                                    "npts":
                                    current["npts"],
                                    "rgba":
                                    current["rgba"],
                                    "values": []
                                })
                                current = geometries["poly"][-1]
                        pt, pt_col, pt_n = get_coords_from_line(line)
                        if pt:
                            current["values"].append({
                                "pos": pt,
                            })
                            color = pt_col or current["rgba"]
                            if color:
                                current["values"][-1]["col"] = color
                            if pt_n:
                                current["values"][-1]["norm"] = pt_n

        # Build lines polydata if there were any lines
        if geometries["lines"]:
            line_points = vtkPoints()
            line_cells = vtkCellArray()
            line_point_colors = vtkFloatArray()
            line_point_colors.SetNumberOfComponents(4)
            line_point_colors.SetName("rgba_colors")
            line_point_normals = vtkFloatArray()
            line_point_normals.SetNumberOfComponents(3)
            line_point_normals.SetName("vertex_normals")

            pt_count = 0

            for batch in geometries["lines"]:
                num_in_batch = len(batch["values"])
                first_in_batch = True
                for coord in batch["values"]:
                    if "pos" in coord:
                        line_points.InsertNextPoint(coord["pos"])
                    if "norm" in coord:
                        line_point_normals.InsertNextTuple(coord["norm"])
                    if "col" in coord:
                        line_point_colors.InsertNextTuple(coord["col"])

                    if first_in_batch:
                        line_cells.InsertNextCell(num_in_batch)
                        first_in_batch = False

                    line_cells.InsertCellPoint(pt_count)

                    pt_count += 1

            output_lines = vtkPolyData()

            output_lines.SetPoints(line_points)
            output_lines.SetLines(line_cells)

            if line_point_colors.GetNumberOfTuples() > 0:
                output_lines.GetPointData().AddArray(line_point_colors)

            if line_point_normals.GetNumberOfTuples() > 0:
                output_lines.GetPointData().AddArray(line_point_normals)

            ds = vtkPartitionedDataSet()
            ds.SetNumberOfPartitions(1)
            ds.SetPartition(0, output_lines)

            partitioned_datasets.append(ds)
            partitioned_dataset_names.append("Lines")

        # Build the points polydata if we found points
        if geometries["points"]:
            p_points = vtkPoints()
            p_cells = vtkCellArray()
            p_point_colors = vtkFloatArray()
            p_point_colors.SetNumberOfComponents(4)
            p_point_colors.SetName("rgba_colors")
            p_point_normals = vtkFloatArray()
            p_point_normals.SetNumberOfComponents(3)
            p_point_normals.SetName("vertex_normals")

            p_count = 0

            for batch in geometries["points"]:
                num_in_batch = len(batch["values"])
                first_in_batch = True
                for coord in batch["values"]:
                    if "pos" in coord:
                        p_points.InsertNextPoint(coord["pos"])
                    if "norm" in coord:
                        p_point_normals.InsertNextTuple(coord["norm"])
                    if "col" in coord:
                        p_point_colors.InsertNextTuple(coord["col"])

                    if first_in_batch:
                        p_cells.InsertNextCell(num_in_batch)
                        first_in_batch = False

                    p_cells.InsertCellPoint(p_count)

                    p_count += 1

            output_points = vtkPolyData()

            output_points.SetPoints(p_points)
            output_points.SetVerts(p_cells)

            if p_point_colors.GetNumberOfTuples() > 0:
                output_points.GetPointData().AddArray(p_point_colors)

            if p_point_normals.GetNumberOfTuples() > 0:
                output_points.GetPointData().AddArray(p_point_normals)

            ds = vtkPartitionedDataSet()
            ds.SetNumberOfPartitions(1)
            ds.SetPartition(0, output_points)

            partitioned_datasets.append(ds)
            partitioned_dataset_names.append("Points")

        # Build the polygons if there were any
        if geometries["poly"]:
            poly_points = vtkPoints()
            poly_cells = vtkCellArray()
            poly_point_colors = vtkFloatArray()
            poly_point_colors.SetNumberOfComponents(4)
            poly_point_colors.SetName("rgba_colors")
            poly_point_normals = vtkFloatArray()
            poly_point_normals.SetNumberOfComponents(3)
            poly_point_normals.SetName("vertex_normals")

            pt_count = 0

            for batch in geometries["poly"]:
                num_in_batch = len(batch["values"])
                if num_in_batch < 1:
                    continue
                first_in_batch = True
                for coord in batch["values"]:
                    if "pos" in coord:
                        poly_points.InsertNextPoint(coord["pos"])
                    if "norm" in coord:
                        poly_point_normals.InsertNextTuple(coord["norm"])
                    if "col" in coord:
                        poly_point_colors.InsertNextTuple(coord["col"])

                    if first_in_batch:
                        np_in_cell = num_in_batch
                        poly_cells.InsertNextCell(np_in_cell)
                        first_in_batch = False

                    poly_cells.InsertCellPoint(pt_count)

                    pt_count += 1

            output_polys = vtkPolyData()

            output_polys.SetPoints(poly_points)
            output_polys.SetPolys(poly_cells)

            if poly_point_colors.GetNumberOfTuples() > 0:
                output_polys.GetPointData().AddArray(poly_point_colors)

            if poly_point_normals.GetNumberOfTuples() > 0:
                output_polys.GetPointData().AddArray(poly_point_normals)

            ds = vtkPartitionedDataSet()
            ds.SetNumberOfPartitions(1)
            ds.SetPartition(0, output_polys)

            partitioned_datasets.append(ds)
            partitioned_dataset_names.append("Polygons")

        # Add any partioned datasets we created
        output.SetNumberOfPartitionedDataSets(len(partitioned_datasets))

        for idx, pds in enumerate(partitioned_datasets):
            output.SetPartitionedDataSet(idx, pds)
            output.GetMetaData(idx).Set(vtkCompositeDataSet.NAME(),
                                        partitioned_dataset_names[idx])

        return 1
예제 #7
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))
예제 #8
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
예제 #9
0
    def writeArray(self, path, source, name, component=0):
        rep = simple.Show(source, self.view)
        rep.Representation = 'Surface'
        rep.DiffuseColor = [1, 1, 1]

        dataRange = [0.0, 1.0]
        fieldToColorBy = ['POINTS', name]

        self.view.ArrayNameToDraw = name
        self.view.ArrayComponentToDraw = component

        pdi = source.GetPointDataInformation()
        cdi = source.GetCellDataInformation()

        if pdi.GetArray(name):
            self.view.DrawCells = 0
            dataRange = pdi.GetArray(name).GetRange(component)
            fieldToColorBy[0] = 'POINTS'
        elif cdi.GetArray(name):
            self.view.DrawCells = 1
            dataRange = cdi.GetArray(name).GetRange(component)
            fieldToColorBy[0] = 'CELLS'
        else:
            print("No array with that name", name)
            return

        realRange = dataRange
        if dataRange[0] == dataRange[1]:
            dataRange = [dataRange[0] - 0.1, dataRange[1] + 0.1]

        simple.ColorBy(rep, fieldToColorBy)

        # Grab data
        tmpFileName = path + '__.png'
        self.view.ScalarRange = dataRange
        self.view.LockBounds = 1
        self.view.StartCaptureValues()
        simple.SaveScreenshot(tmpFileName, self.view)
        self.view.StopCaptureValues()
        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 = vtkFloatArray()
            rawArray.SetNumberOfTuples(arraySize)

            minValue = 10000.0
            maxValue = -100000.0
            delta = (dataRange[1] -
                     dataRange[0]) / 16777215.0  # 2^24 - 1 => 16,777,215
            for idx in range(arraySize):
                rgb = rgbArray.GetTuple3(idx)
                if rgb[0] != 0 or rgb[1] != 0 or rgb[2] != 0:
                    value = dataRange[0] + delta * float(
                        rgb[0] * 65536 + rgb[1] * 256 + rgb[2] - 1)
                    rawArray.SetTuple1(idx, value)
                    minValue = min(value, minValue)
                    maxValue = max(value, maxValue)
                else:
                    rawArray.SetTuple1(idx, float('NaN'))

            # print ('Array bounds', minValue, maxValue, 'compare to', dataRange)

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

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

        # Remove representation from view
        simple.Hide(source, self.view)

        return realRange
예제 #10
0
    def _do_surface_creation(self, mask, mask_sFormMatrix=None):
        if mask_sFormMatrix is None:
            mask_sFormMatrix = vtkMatrix4x4()

        value = np.mean(mask.GetScalarRange())

        # Use the mask to create isosurface
        mc = vtkContourFilter()
        mc.SetInputData(mask)
        mc.SetValue(0, value)
        mc.ComputeNormalsOn()
        mc.Update()

        # Mask isosurface
        refSurface = mc.GetOutput()

        # Create a uniformly meshed surface
        tmpPeel = downsample(refSurface)
        # Standard space coordinates

        # Apply coordinate transform to the meshed mask
        mask_ijk2xyz = vtkTransform()
        mask_ijk2xyz.SetMatrix(mask_sFormMatrix)

        mask_ijk2xyz_filter = vtkTransformPolyDataFilter()
        mask_ijk2xyz_filter.SetInputData(tmpPeel)
        mask_ijk2xyz_filter.SetTransform(mask_ijk2xyz)
        mask_ijk2xyz_filter.Update()

        # Smooth the mesh
        tmpPeel = smooth(mask_ijk2xyz_filter.GetOutput())
        # Configure calculation of normals
        tmpPeel = fixMesh(tmpPeel)
        # Remove duplicate points etc
        # tmpPeel = cleanMesh(tmpPeel)
        # Generate triangles
        tmpPeel = upsample(tmpPeel)

        tmpPeel = smooth(tmpPeel)
        tmpPeel = fixMesh(tmpPeel)
        tmpPeel = cleanMesh(tmpPeel)

        refImageSpace2_xyz_transform = vtkTransform()
        refImageSpace2_xyz_transform.SetMatrix(vtk_utils.numpy_to_vtkMatrix4x4(np.linalg.inv(self.affine)))

        self.refImageSpace2_xyz = vtkTransformPolyDataFilter()
        self.refImageSpace2_xyz.SetTransform(refImageSpace2_xyz_transform)

        xyz2_refImageSpace_transform = vtkTransform()
        xyz2_refImageSpace_transform.SetMatrix(vtk_utils.numpy_to_vtkMatrix4x4(self.affine))

        self.xyz2_refImageSpace = vtkTransformPolyDataFilter()
        self.xyz2_refImageSpace.SetTransform(xyz2_refImageSpace_transform)

        currentPeel = tmpPeel
        self.currentPeelNo = 0
        currentPeel= self.MapImageOnCurrentPeel(currentPeel)

        newPeel = vtkPolyData()
        newPeel.DeepCopy(currentPeel)
        newPeel.DeepCopy(currentPeel)
        self.peel_normals = vtkFloatArray()
        self.peel_centers = vtkFloatArray()
        self.peel.append(newPeel)
        self.currentPeelActor = vtkActor()
        if not np.all(np.equal(self.affine, np.eye(4))):
            affine_vtk = self.CreateTransformedVTKAffine()
            self.currentPeelActor.SetUserMatrix(affine_vtk)
        self.GetCurrentPeelActor(currentPeel)
        self.peelActors.append(self.currentPeelActor)
        # locator will later find the triangle on the peel surface where the coil's normal intersect
        self.locator = vtkCellLocator()
        self.PeelDown(currentPeel)
예제 #11
0
    def writeArray(self, path, source, name, component=0):
        rep = simple.Show(source, self.view)
        rep.Representation = 'Surface'
        rep.DiffuseColor = [1,1,1]

        dataRange = [0.0, 1.0]
        fieldToColorBy = ['POINTS', name]

        self.view.ArrayNameToDraw = name
        self.view.ArrayComponentToDraw = component

        pdi = source.GetPointDataInformation()
        cdi = source.GetCellDataInformation()

        if pdi.GetArray(name):
            self.view.DrawCells = 0
            dataRange = pdi.GetArray(name).GetRange(component)
            fieldToColorBy[0] = 'POINTS'
        elif cdi.GetArray(name):
            self.view.DrawCells = 1
            dataRange = cdi.GetArray(name).GetRange(component)
            fieldToColorBy[0] = 'CELLS'
        else:
            print ("No array with that name", name)
            return

        realRange = dataRange
        if dataRange[0] == dataRange[1]:
          dataRange = [dataRange[0] - 0.1, dataRange[1] + 0.1]

        simple.ColorBy(rep, fieldToColorBy)

        # Grab data
        tmpFileName = path + '__.png'
        self.view.ScalarRange = dataRange
        self.view.LockBounds = 1
        self.view.StartCaptureValues()
        simple.SaveScreenshot(tmpFileName, self.view)
        self.view.StopCaptureValues()
        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 = vtkFloatArray()
            rawArray.SetNumberOfTuples(arraySize)

            minValue = 10000.0
            maxValue = -100000.0
            delta = (dataRange[1] - dataRange[0]) / 16777215.0 # 2^24 - 1 => 16,777,215
            for idx in range(arraySize):
                rgb = rgbArray.GetTuple3(idx)
                if rgb[0] != 0 or rgb[1] != 0 or rgb[2] != 0:
                    value = dataRange[0] + delta * float(rgb[0]*65536 + rgb[1]*256 + rgb[2] - 1)
                    rawArray.SetTuple1(idx, value)
                    minValue = min(value, minValue)
                    maxValue = max(value, maxValue)
                else:
                    rawArray.SetTuple1(idx, float('NaN'))

            # print ('Array bounds', minValue, maxValue, 'compare to', dataRange)

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

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

        # Remove representation from view
        simple.Hide(source, self.view)

        return realRange
예제 #12
0
    def writeData(self, time=0):
        if not self.dataHandler.can_write:
            return

        currentScene = [];
        for data in self.config['scene']:
            currentData = {
                'name': data['name'],
                'fields': {}
            }
            currentScene.append(currentData)
            if self.surfaceExtract:
                self.merge.Input = data['source']
            else:
                self.merge = simple.MergeBlocks(Input=data['source'], MergePoints=0)
                self.surfaceExtract = simple.ExtractSurface(Input=self.merge)


            # Extract surface
            self.surfaceExtract.UpdatePipeline(time)
            ds = self.surfaceExtract.SMProxy.GetClientSideObject().GetOutputDataObject(0)
            originalDS = data['source'].SMProxy.GetClientSideObject().GetOutputDataObject(0)

            originalPoints = ds.GetPoints()

            # Points
            points = vtkFloatArray()
            nbPoints = originalPoints.GetNumberOfPoints()
            points.SetNumberOfComponents(3)
            points.SetNumberOfTuples(nbPoints)
            for idx in range(nbPoints):
                coord = originalPoints.GetPoint(idx)
                points.SetTuple3(idx, coord[0], coord[1], coord[2])

            pBuffer = buffer(points)
            pMd5 = hashlib.md5(pBuffer).hexdigest()
            pPath = os.path.join(self.dataHandler.getBasePath(), 'points',"%s.Float32Array" % pMd5)
            currentData['points'] = 'points/%s.Float32Array' % pMd5
            with open(pPath, 'wb') as f:
                f.write(pBuffer)

            # Polys
            poly = ds.GetPolys()
            nbCells = poly.GetNumberOfCells()
            cellLocation = 0
            idList = vtkIdList()
            topo = vtkTypeUInt32Array()
            topo.Allocate(poly.GetData().GetNumberOfTuples())

            for cellIdx in range(nbCells):
                poly.GetCell(cellLocation, idList)
                cellSize = idList.GetNumberOfIds()
                cellLocation += cellSize + 1
                if cellSize == 3:
                    topo.InsertNextValue(idList.GetId(0))
                    topo.InsertNextValue(idList.GetId(1))
                    topo.InsertNextValue(idList.GetId(2))
                elif cellSize == 4:
                    topo.InsertNextValue(idList.GetId(0))
                    topo.InsertNextValue(idList.GetId(1))
                    topo.InsertNextValue(idList.GetId(3))
                    topo.InsertNextValue(idList.GetId(1))
                    topo.InsertNextValue(idList.GetId(2))
                    topo.InsertNextValue(idList.GetId(3))
                else:
                    print ("Cell size of", cellSize, "not supported")

            iBuffer = buffer(topo)
            iMd5 = hashlib.md5(iBuffer).hexdigest()
            iPath = os.path.join(self.dataHandler.getBasePath(), 'index',"%s.Uint32Array" % iMd5)
            currentData['index'] = 'index/%s.Uint32Array' % iMd5
            with open(iPath, 'wb') as f:
                f.write(iBuffer)

            # Grow object side
            self.objSize[data['name']]['points'] = max(self.objSize[data['name']]['points'], nbPoints)
            self.objSize[data['name']]['index'] = max(self.objSize[data['name']]['index'], topo.GetNumberOfTuples())

            # Colors / FIXME
            for fieldName, fieldInfo in iteritems(data['colors']):
                array = ds.GetPointData().GetArray(fieldName)
                tupleSize = array.GetNumberOfComponents()
                arraySize = array.GetNumberOfTuples()
                outputField = vtkFloatArray()
                outputField.SetNumberOfTuples(arraySize)
                if tupleSize == 1:
                    for i in range(arraySize):
                        outputField.SetValue(i, array.GetValue(i))
                else:
                    # compute magnitude
                    tupleIdxs = range(tupleSize)
                    for i in range(arraySize):
                        magnitude = 0
                        for j in tupleIdxs:
                            magnitude += math.pow(array.GetValue(i * tupleSize + j), 2)

                        outputField.SetValue(i, math.sqrt(magnitude))

                fBuffer = buffer(outputField)
                fMd5 = hashlib.md5(fBuffer).hexdigest()
                fPath = os.path.join(self.dataHandler.getBasePath(), 'fields',"%s_%s.Float32Array" % (fieldName, fMd5))
                with open(fPath, 'wb') as f:
                    f.write(fBuffer)

                currentData['fields'][fieldName] = 'fields/%s_%s.Float32Array' % (fieldName, fMd5)

        # Write scene
        with open(self.dataHandler.getDataAbsoluteFilePath('scene'), 'w') as f:
            f.write(json.dumps(currentScene, indent=2))
예제 #13
0
    def writeData(self, time=0):
        if not self.dataHandler.can_write:
            return

        currentScene = [];
        for data in self.config['scene']:
            currentData = {
                'name': data['name'],
                'fields': {},
                'cells': {}
            }
            currentScene.append(currentData)
            if self.surfaceExtract:
                self.merge.Input = data['source']
            else:
                self.merge = simple.MergeBlocks(Input=data['source'], MergePoints=0)
                self.surfaceExtract = simple.ExtractSurface(Input=self.merge)


            # Extract surface
            self.surfaceExtract.UpdatePipeline(time)
            ds = self.surfaceExtract.SMProxy.GetClientSideObject().GetOutputDataObject(0)
            originalDS = data['source'].SMProxy.GetClientSideObject().GetOutputDataObject(0)

            originalPoints = ds.GetPoints()

            # Points
            points = vtkFloatArray()
            nbPoints = originalPoints.GetNumberOfPoints()
            points.SetNumberOfComponents(3)
            points.SetNumberOfTuples(nbPoints)
            for idx in range(nbPoints):
                coord = originalPoints.GetPoint(idx)
                points.SetTuple3(idx, coord[0], coord[1], coord[2])

            pBuffer = buffer(points)
            pMd5 = hashlib.md5(pBuffer).hexdigest()
            pPath = os.path.join(self.dataHandler.getBasePath(), 'data',"%s.Float32Array" % pMd5)
            currentData['points'] = 'data/%s.Float32Array' % pMd5
            with open(pPath, 'wb') as f:
                f.write(pBuffer)

            # Handle cells
            writeCellArray(self.dataHandler, currentData['cells'], 'verts', ds.GetVerts().GetData())
            writeCellArray(self.dataHandler, currentData['cells'], 'lines', ds.GetLines().GetData())
            writeCellArray(self.dataHandler, currentData['cells'], 'polys', ds.GetPolys().GetData())
            writeCellArray(self.dataHandler, currentData['cells'], 'strips', ds.GetStrips().GetData())

            # Fields
            for fieldName, fieldInfo in iteritems(data['colors']):
                array = None
                if 'constant' in fieldInfo:
                    currentData['fields'][fieldName] = fieldInfo
                    continue
                elif 'POINT_DATA' in fieldInfo['location']:
                    array = ds.GetPointData().GetArray(fieldName)
                elif 'CELL_DATA' in fieldInfo['location']:
                    array = ds.GetCellData().GetArray(fieldName)
                jsType = jsMapping[arrayTypesMapping[array.GetDataType()]]
                arrayRange = array.GetRange(-1)
                tupleSize = array.GetNumberOfComponents()
                arraySize = array.GetNumberOfTuples()
                if tupleSize == 1:
                    outputField = array
                else:
                    # compute magnitude
                    outputField = array.NewInstance()
                    outputField.SetNumberOfTuples(arraySize)
                    tupleIdxs = range(tupleSize)
                    for i in range(arraySize):
                        magnitude = 0
                        for j in tupleIdxs:
                            magnitude += math.pow(array.GetValue(i * tupleSize + j), 2)

                        outputField.SetValue(i, math.sqrt(magnitude))

                fBuffer = buffer(outputField)
                fMd5 = hashlib.md5(fBuffer).hexdigest()
                fPath = os.path.join(self.dataHandler.getBasePath(), 'data',"%s_%s.%s" % (fieldName, fMd5, jsType))
                with open(fPath, 'wb') as f:
                    f.write(fBuffer)

                currentRange = self.ranges[fieldName]
                if currentRange[1] < currentRange[0]:
                    currentRange[0] = arrayRange[0];
                    currentRange[1] = arrayRange[1];
                else:
                    currentRange[0] = arrayRange[0] if arrayRange[0] < currentRange[0] else currentRange[0];
                    currentRange[1] = arrayRange[1] if arrayRange[1] > currentRange[1] else currentRange[1];

                currentData['fields'][fieldName] = {
                    'array' : 'data/%s_%s.%s' % (fieldName, fMd5, jsType),
                    'location': fieldInfo['location'],
                    'range': outputField.GetRange()
                }

        # Write scene
        with open(self.dataHandler.getDataAbsoluteFilePath('scene'), 'w') as f:
            f.write(json.dumps(currentScene, indent=4))
예제 #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)
예제 #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))
예제 #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