def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--label", type=int, required=False)
    parser.add_argument("input_hdf5_file")
    parsed_args = parser.parse_args()

    output_file = os.path.splitext(parsed_args.input_hdf5_file)[0] + ".obj"

    print "Loading volume..."
    with h5py.File(parsed_args.input_hdf5_file, 'r') as f_input:
        dataset_names = []
        f_input.visit(dataset_names.append)
        if len(dataset_names) != 1:
            sys.stderr.write("Input HDF5 file should have exactly 1 dataset.\n")
            sys.exit(1)
        volume = f_input[dataset_names[0]][:].squeeze()

    if parsed_args.label:
        volume[:] = (volume == parsed_args.label)
    else:
        volume[:] = (volume != 0)
    
    app = QApplication([])

    dlg = MeshExtractorDialog()
    dlg.finished.connect( partial(onMeshesComplete, dlg, output_file) )
    dlg.show()
    dlg.raise_()

    QTimer.singleShot(0, partial(dlg.run, volume, [0]))
    app.exec_()
    print "DONE."
Example #2
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--label", type=int, required=False)
    parser.add_argument("input_hdf5_file")
    parsed_args = parser.parse_args()

    output_file = os.path.splitext(parsed_args.input_hdf5_file)[0] + ".obj"

    print "Loading volume..."
    with h5py.File(parsed_args.input_hdf5_file, 'r') as f_input:
        dataset_names = []
        f_input.visit(dataset_names.append)
        if len(dataset_names) != 1:
            sys.stderr.write(
                "Input HDF5 file should have exactly 1 dataset.\n")
            sys.exit(1)
        volume = f_input[dataset_names[0]][:].squeeze()

    if parsed_args.label:
        volume[:] = (volume == parsed_args.label)
    else:
        volume[:] = (volume != 0)

    app = QApplication([])

    dlg = MeshExtractorDialog()
    dlg.finished.connect(partial(onMeshesComplete, dlg, output_file))
    dlg.show()
    dlg.raise_()

    QTimer.singleShot(0, partial(dlg.run, volume, [0]))
    app.exec_()
    print "DONE."
Example #3
0
    def _exportMeshes(self, object_names, obj_filepaths):
        """
        Export a mesh .obj file for each object in the object_names list to the corresponding file name from the obj_filepaths list.
        This function is pseudo-recursive. It works like this:
        1) Pop the first name/file from the args
        2) Kick off the export by launching the export mesh dlg
        3) return from this function to allow the eventloop to resume while the export is running
        4) When the export dlg is finished, create the mesh file (by writing a temporary .vtk file and converting it into a .obj file)
        5) If there are still more items in the object_names list to process, repeat this function.
        """
        # Pop the first object off the list
        object_name = object_names.pop(0)
        obj_filepath = obj_filepaths.pop(0)
        
        # Construct a volume with only this object.
        # We might be tempted to get the object directly from opCarving.DoneObjects, 
        #  but that won't be correct for overlapping objects.
        mst = self.topLevelOperatorView.MST.value
        object_supervoxels = mst.object_lut[object_name]
        object_lut = numpy.zeros(mst.nodeNum+1, dtype=numpy.int32)
        object_lut[object_supervoxels] = 1
        supervoxel_volume = mst.supervoxelUint32
        object_volume = object_lut[supervoxel_volume]

        # Run the mesh extractor
        window = MeshExtractorDialog(parent=self)
        
        def onMeshesComplete():
            """
            Called when mesh extraction is complete.
            Writes the extracted mesh to an .obj file
            """
            logger.info( "Mesh generation complete." )
            mesh_count = len( window.extractor.meshes )

            # Mesh count can sometimes be 0 for the '<not saved yet>' object...
            if mesh_count > 0:
                assert mesh_count == 1, \
                    "Found {} meshes processing object '{}',"\
                    "(only expected 1)".format( mesh_count, object_name )
                mesh = window.extractor.meshes.values()[0]
                logger.info( "Saving meshes to {}".format( obj_filepath ) )
    
                # Use VTK to write to a temporary .vtk file
                tmpdir = tempfile.mkdtemp()
                vtkpoly_path = os.path.join(tmpdir, 'meshes.vtk')
                w = vtkPolyDataWriter()
                w.SetFileTypeToASCII()
                w.SetInput(mesh)
                w.SetFileName(vtkpoly_path)
                w.Write()
                
                # Now convert the file to .obj format.
                convertVTPtoOBJ(vtkpoly_path, obj_filepath)
    
            # Cleanup: We don't need the window anymore.
            window.setParent(None)

            # If there are still objects left to process,
            #   start again with the remainder of the list.
            if object_names:
                self._exportMeshes(object_names, obj_filepaths)
            
        window.finished.connect( onMeshesComplete )

        # Kick off the save process and exit to the event loop
        window.show()
        QTimer.singleShot(0, partial(window.run, object_volume, [0]))
Example #4
0
    def _exportMeshes(self, object_names, obj_filepaths):
        """
        Export a mesh .obj file for each object in the object_names list to the corresponding file name from the obj_filepaths list.
        This function is pseudo-recursive. It works like this:
        1) Pop the first name/file from the args
        2) Kick off the export by launching the export mesh dlg
        3) return from this function to allow the eventloop to resume while the export is running
        4) When the export dlg is finished, create the mesh file (by writing a temporary .vtk file and converting it into a .obj file)
        5) If there are still more items in the object_names list to process, repeat this function.
        """
        # Pop the first object off the list
        object_name = object_names.pop(0)
        obj_filepath = obj_filepaths.pop(0)
        
        # Construct a volume with only this object.
        # We might be tempted to get the object directly from opCarving.DoneObjects, 
        #  but that won't be correct for overlapping objects.
        mst = self.topLevelOperatorView.MST.value
        object_supervoxels = mst.object_lut[object_name]
        object_lut = numpy.zeros(len(mst.objects.lut), dtype=numpy.int32)
        object_lut[object_supervoxels] = 1
        supervoxel_volume = mst.regionVol
        object_volume = object_lut[supervoxel_volume]

        # Run the mesh extractor
        window = MeshExtractorDialog(parent=self)
        
        def onMeshesComplete():
            """
            Called when mesh extraction is complete.
            Writes the extracted mesh to an .obj file
            """
            logger.info( "Mesh generation complete." )
            mesh_count = len( window.extractor.meshes )

            # Mesh count can sometimes be 0 for the '<not saved yet>' object...
            if mesh_count > 0:
                assert mesh_count == 1, \
                    "Found {} meshes processing object '{}',"\
                    "(only expected 1)".format( mesh_count, object_name )
                mesh = window.extractor.meshes.values()[0]
                logger.info( "Saving meshes to {}".format( obj_filepath ) )
    
                # Use VTK to write to a temporary .vtk file
                tmpdir = tempfile.mkdtemp()
                vtkpoly_path = os.path.join(tmpdir, 'meshes.vtk')
                w = vtkPolyDataWriter()
                w.SetFileTypeToASCII()
                w.SetInput(mesh)
                w.SetFileName(vtkpoly_path)
                w.Write()
                
                # Now convert the file to .obj format.
                convertVTPtoOBJ(vtkpoly_path, obj_filepath)
    
            # Cleanup: We don't need the window anymore.
            window.setParent(None)

            # If there are still objects left to process,
            #   start again with the remainder of the list.
            if object_names:
                self._exportMeshes(object_names, obj_filepaths)
            
        window.finished.connect( onMeshesComplete )

        # Kick off the save process and exit to the event loop
        window.show()
        QTimer.singleShot(0, partial(window.run, object_volume, [0]))