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)
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)
def writeData(self, time=0): if not self.dataHandler.can_write: return self.resamplerFilter.UpdatePipeline(time) imageData = self.resamplerFilter.GetClientSideObject().GetOutput() self.DataProber['spacing'] = imageData.GetSpacing() arrays = imageData.GetPointData() maskArray = arrays.GetArray(vtkDataSetAttributes.GhostArrayName()) for field in self.fieldsToWrite: array = arrays.GetArray(field) if array: if array.GetNumberOfComponents() == 1: # Push NaN when no value are present instead of 0 for idx in range(maskArray.GetNumberOfTuples()): if maskArray.GetValue(idx) == 2: # Hidden point array.SetValue(idx, float('NaN')) with open(self.dataHandler.getDataAbsoluteFilePath(field), 'wb') as f: f.write(buffer(array)) self.expandRange(array) else: magarray = array.NewInstance() magarray.SetNumberOfTuples(array.GetNumberOfTuples()) magarray.SetName(field) for idx in range(magarray.GetNumberOfTuples()): if maskArray.GetValue(idx) == 2: # Hidden point # Push NaN when no value are present magarray.SetValue(idx, float('NaN')) else: entry = array.GetTuple(idx) mag = self.magnitude(entry) magarray.SetValue(idx,mag) with open(self.dataHandler.getDataAbsoluteFilePath(field), 'wb') as f: f.write(buffer(magarray)) self.expandRange(magarray) else: print ('No array for', field) print (self.resamplerFilter.GetOutput())
def writeCellArray(dataHandler, currentData, cellName, inputCellArray): nbValues = inputCellArray.GetNumberOfTuples() if nbValues == 0: return outputCells = vtkTypeUInt32Array() outputCells.SetNumberOfTuples(nbValues) for valueIdx in range(nbValues): outputCells.SetValue(valueIdx, inputCellArray.GetValue(valueIdx)) iBuffer = buffer(outputCells) iMd5 = hashlib.md5(iBuffer).hexdigest() iPath = os.path.join(dataHandler.getBasePath(), 'data',"%s.Uint32Array" % iMd5) currentData['polys'] = 'data/%s.Uint32Array' % iMd5 with open(iPath, 'wb') as f: f.write(iBuffer)
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
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
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
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))
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
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
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))
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))
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)
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))
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