def main(argv):
    inputfile = ''
    outputfile = ''
    propfile = ''
    try:
        opts, args = getopt.getopt(argv, "hd:f:D:",
                                   ["ifile=", "ofile=", "dfil="])
    except getopt.GetoptError:
        print('test.py -d <inputfile> -f <outputfile> -D <propfile>')
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-h':
            print('test.py -d <inputfile> -f <outputfile> -D <propfile>')
            sys.exit()
        elif opt in ("-d", "--ifile"):
            inputfile = arg
        elif opt in ("-f", "--ofile"):
            outputfile = arg
        elif opt in ("-D", "--dfile"):
            propfile = arg

    print("LuxCore %s" % pyluxcore.Version())
    pyluxcore.Init(LogHandler)
    app = QApplication.instance()
    if app is None:
        app = QApplication(sys.argv)
    window = MainWindow(inputfile, outputfile, propfile)
    if propfile == "":
        window.show()
    app.exec_()
Beispiel #2
0
    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        self.setupUi(self)

        if not PYSIDE2:
            self.move(
                QtWidgets.QApplication.desktop().screen().rect().center() -
                self.rect().center())

        uiloghandler.AddUILogHandler(loghandler.loggerName, self)

        ipRegExp = QtCore.QRegExp(
            "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
        )
        self.lineEditIPAddress.setValidator(QtGui.QRegExpValidator(ipRegExp))
        self.lineEditPort.setValidator(QtGui.QIntValidator(0, 65535))
        self.lineEditBroadcastAddress.setValidator(
            QtGui.QRegExpValidator(ipRegExp))

        self.__ResetConfigUI()

        logger.info("LuxCore %s" % pyluxcore.Version())

        self.renderFarmNode = None

        self.PrintMsg("Waiting for configuration...")
Beispiel #3
0
def main(argv):
    pyluxcore.Init(LogHandler)
    print("LuxCore %s" % pyluxcore.Version())

    # Get the command line options
    try:
        opts, args = getopt.getopt(argv[1:], "hH:p:q",
                                   ["help", "host=", "port=", "quiet"])
    except getopt.GetoptError:
        usage()
        sys.exit(-1)

    host = "localhost"
    port = 18081
    logOutput = sys.stdout
    for opt, arg in opts:
        if opt == '-h':
            usage()
            sys.exit()
        if opt in ('-H', '--host'):
            host = arg
        if opt in ('-p', '--port'):
            port = int(arg)
        if opt in ('-q', '--quiet'):
            logOutput = None
    print("Hostname: %s Port: %d" % (host, port))

    global qapp
    qapp = QApplication(sys.argv)

    while True:
        server = LuxCoreTelnetServer(host, port, logOutput)
        server.handleConnection()

    sys.exit(app.exec_())
Beispiel #4
0
def main(argv):
	try:
		pyluxcore.Init(pyluxcoretools.utils.loghandler.LuxCoreLogHandler)
		logger.info("LuxCore %s" % pyluxcore.Version())

		LuxCoreMerge(argv[1:])
	finally:
		pyluxcore.SetLogHandler(None)
Beispiel #5
0
def main():
	print("LuxCore %s" % pyluxcore.Version())
	pyluxcore.Init(LogHandler)
	
	app = QApplication(sys.argv)
	rv = RenderView()
	rv.show()
	app.exec_()
Beispiel #6
0
def main():
    pyluxcore.Init()

    print("LuxCore %s" % pyluxcore.Version())
    #print("OS:", os.name)

    SaveFilm()
    LoadFilm()
def main():
	pyluxcore.Init(LogHandler)
	print("LuxCore %s" % pyluxcore.Version())
	
	app = QApplication(sys.argv)
	rv = RenderView("scenes/luxball/luxball-hdr.cfg")
	rv.show()
	sys.exit(app.exec_())
Beispiel #8
0
def main(argv):
	try:
		pyluxcore.Init(loghandler.LuxCoreLogHandler)
		logger.info("LuxCore %s" % pyluxcore.Version())

		LuxCoreNetNode(argv[1:])
	finally:
		pyluxcore.SetLogHandler(None)
Beispiel #9
0
def main():
    pyluxcore.Init(LogHandler)

    print("LuxCore %s" % pyluxcore.Version())

    #PropertiesTest()
    #SceneTest()
    #RenderConfigTest()
    SimpleRenderTest()
Beispiel #10
0
def main(argv):
	try:
		pyluxcore.Init(loghandler.LuxCoreLogHandlerDebug)
		logger.info("LuxCore %s" % pyluxcore.Version())

		netConsole = LuxCoreNetConsole()
		netConsole.Exec(argv[1:])
	finally:
		pyluxcore.SetLogHandler(None)
Beispiel #11
0
def main(argv):
    try:
        pyluxcore.Init(pyluxcoretools.utils.loghandler.LuxCoreLogHandler)
        logger.info("LuxCore %s" % pyluxcore.Version())

        pyluxcore.AddFileNameResolverPath(".")

        LuxCoreConsole(argv[1:])
    finally:
        pyluxcore.SetLogHandler(None)
Beispiel #12
0
def main():
	pyluxcore.Init()

	print("LuxCore %s" % pyluxcore.Version())
	#print("OS:", os.name)
	
	#PropertiesTests()
	#LuxRaysDeviceTests()
	#SimpleRender()
	#GetOutputTest()
	#ExtractConfiguration()
	StrandsRender()
Beispiel #13
0
def main():
    pyluxcore.Init()

    print("LuxCore %s" % pyluxcore.Version())
    #print("OS:", os.name)

    PropertiesTests()
    LuxRaysDeviceTests()
    SimpleRender()
    GetOutputTest()
    ExtractConfiguration()
    StrandsRender()
    ImagePipelineEdit()
    SaveResumeRenderingM()
    SaveResumeRenderingS()
Beispiel #14
0
    def __HandleConnection(self, clientSocket, addr):
        id = str(uuid.uuid4())
        renderConfigFile = "renderfarmnode-" + id + ".bcf"
        filmFile = "renderfarmnode-" + id + ".flm"
        try:
            logger.info("Received connection from: " + str(addr))

            #-----------------------------------------------------------
            # Check pyluxcore version
            #-----------------------------------------------------------

            remoteVersion = socketutils.RecvLine(clientSocket)
            logger.info("Remote pyluxcore version: " + remoteVersion)
            logger.info("Local pyluxcore version: " + pyluxcore.Version())
            if (remoteVersion != pyluxcore.Version()):
                logger.info("No matching pyluxcore versions !")
                socketutils.SendLine(
                    clientSocket,
                    "ERROR: wrong pyluxcore version" + pyluxcore.Version())
                return
            socketutils.SendLine(clientSocket, "OK")

            #-----------------------------------------------------------
            # Receive the RenderConfig serialized file
            #-----------------------------------------------------------

            logger.info("Receiving RenderConfig serialized file: " +
                        renderConfigFile)
            socketutils.RecvFile(clientSocket, renderConfigFile)
            logger.info("Receiving RenderConfig serialized MD5: " +
                        md5utils.md5sum(renderConfigFile))

            #-----------------------------------------------------------
            # Receive the seed
            #-----------------------------------------------------------

            seed = socketutils.RecvLine(clientSocket)
            logger.info("Received seed: " + seed)
            seed = int(seed)

            #-----------------------------------------------------------
            # Read the RenderConfig serialized file
            #-----------------------------------------------------------

            logger.info("Reading RenderConfig serialized file: " +
                        renderConfigFile)
            config = pyluxcore.RenderConfig(renderConfigFile)
            # Sanitize the RenderConfig
            self.__SanitizeRenderConfig(config)
            config.Parse(self.customProperties)

            #-----------------------------------------------------------
            # Start the rendering
            #-----------------------------------------------------------

            session = pyluxcore.RenderSession(config)
            session.Start()

            try:
                socketutils.SendLine(clientSocket, "RENDERING_STARTED")

                statsLine = "Not yet avilable"
                while not self.threadStop:
                    result = socketutils.RecvLineWithTimeOut(clientSocket, 0.2)
                    # Check if there was the timeout
                    if result == None:
                        continue
                    logger.info("Received command: " + result)

                    #-------------------------------------------------------
                    # Update statistics
                    #-------------------------------------------------------

                    session.UpdateStats()

                    stats = session.GetStats()
                    elapsedTime = stats.Get(
                        "stats.renderengine.time").GetFloat()
                    currentPass = stats.Get(
                        "stats.renderengine.pass").GetInt()

                    statsLine = "[Elapsed time: %3dsec][Samples %4d][Avg. samples/sec % 3.2fM on %.1fK tris]" % (
                        elapsedTime, currentPass,
                        stats.Get("stats.renderengine.total.samplesec"
                                  ).GetFloat() / 1000000.0,
                        stats.Get("stats.dataset.trianglecount").GetFloat() /
                        1000.0)

                    #-------------------------------------------------------
                    # Execute the command
                    #-------------------------------------------------------

                    if (result.startswith("ERROR")):
                        logger.info(result)
                        return
                    elif (result == "GET_STATS"):
                        socketutils.SendLine(clientSocket, statsLine)
                    elif (result == "GET_FILM"):
                        # Save the film to a file
                        session.GetFilm().SaveFilm(filmFile)

                        # Transmit the film file
                        socketutils.SendFile(clientSocket, filmFile)
                    elif (result == "DONE"):
                        socketutils.SendOk(clientSocket)
                        break
                    else:
                        raise SyntaxError("Unknow command: " + result)

                    #-------------------------------------------------------
                    # Print some information about the rendering progress
                    #-------------------------------------------------------

                    logger.info(statsLine)
            finally:
                session.Stop()
        except KeyboardInterrupt:
            raise
        except Exception as e:
            logger.exception(e)
        finally:
            try:
                os.remove(filmFile)
            except OSError:
                pass
            try:
                os.remove(filmFile + ".bak")
            except OSError:
                pass
            try:
                os.remove(renderConfigFile)
            except OSError:
                pass

            try:
                clientSocket.shutdown(socket.SHUT_RDWR)
            except:
                pass

            try:
                clientSocket.close()
            except:
                pass

            logger.info("Connection done: " + str(addr))
Beispiel #15
0
    def __init__(self, parent=None):
        super(MainApp, self).__init__(parent)
        self.setupUi(self)

        if PYSIDE_V < 5:
            self.move(
                QtWidgets.QApplication.desktop().screen().rect().center() -
                self.rect().center())

        uiloghandler.AddUILogHandler(loghandler.loggerName, self)

        self.tabWidgetMain.setTabEnabled(0, False)
        self.tabWidgetMain.setCurrentIndex(1)

        self.lineEditHaltSPP.setValidator(QtGui.QIntValidator(0, 9999999))
        self.lineEditHaltTime.setValidator(QtGui.QIntValidator(0, 9999999))
        self.lineEditFilmUpdatePeriod.setValidator(
            QtGui.QIntValidator(0, 9999999))
        self.lineEditStatsPeriod.setValidator(QtGui.QIntValidator(1, 9999999))

        logger.info("LuxCore %s" % pyluxcore.Version())

        #-----------------------------------------------------------------------
        # Create the render farm
        #-----------------------------------------------------------------------

        self.renderFarm = renderfarm.RenderFarm()
        self.renderFarm.Start()

        #-----------------------------------------------------------------------
        # Start the beacon receiver
        #-----------------------------------------------------------------------

        self.beacon = netbeacon.NetBeaconReceiver(
            functools.partial(MainApp.__NodeDiscoveryCallBack, self))
        self.beacon.Start()

        #-----------------------------------------------------------------------
        # Create the queued jobs widget table
        #-----------------------------------------------------------------------

        self.queuedJobsTableModel = QueuedJobsTableModel(self, self.renderFarm)
        self.queuedJobsTableView = QtWidgets.QTableView()
        self.queuedJobsTableView.setModel(self.queuedJobsTableModel)
        self.queuedJobsTableView.resizeColumnsToContents()

        self.vboxLayoutQueuedJobs = QtWidgets.QVBoxLayout(
            self.scrollAreaQueuedJobs)
        self.vboxLayoutQueuedJobs.setObjectName("vboxLayoutQueuedJobs")
        self.vboxLayoutQueuedJobs.addWidget(self.queuedJobsTableView)
        self.scrollAreaQueuedJobs.setLayout(self.vboxLayoutQueuedJobs)

        #-----------------------------------------------------------------------
        # Create the nodes widget table
        #-----------------------------------------------------------------------

        self.nodesTableModel = NodesTableModel(self, self.renderFarm)
        self.nodesTableView = QtWidgets.QTableView()
        self.nodesTableView.setModel(self.nodesTableModel)
        self.nodesTableView.resizeColumnsToContents()

        self.vboxLayoutNodes = QtWidgets.QVBoxLayout(self.scrollAreaNodes)
        self.vboxLayoutNodes.setObjectName("vboxLayoutNodes")
        self.vboxLayoutNodes.addWidget(self.nodesTableView)
        self.scrollAreaNodes.setLayout(self.vboxLayoutNodes)

        #-----------------------------------------------------------------------

        self.renderFarm.SetJobsUpdateCallBack(
            functools.partial(MainApp.__RenderFarmJobsUpdateCallBack, self))
        self.__RenderFarmJobsUpdateCallBack()

        self.renderFarm.SetNodesUpdateCallBack(
            functools.partial(MainApp.__RenderFarmNodesUpdateCallBack, self))
        self.__RenderFarmNodesUpdateCallBack()
Beispiel #16
0
def main():
    print("LuxCore Unit tests")
    print("LuxCore %s" % pyluxcore.Version())

    # Delete all images in the images directory
    print("Deleting all images...", end="")
    folder = 'images'
    for f in [png for png in os.listdir(folder) if png.endswith(".png")]:
        filePath = os.path.join(folder, f)
        os.unlink(filePath)
    print("ok")

    pyluxcore.Init(LuxCoreLogHandler)

    # Parse command line options

    parser = argparse.ArgumentParser(description='Runs LuxCore test suite.')
    parser.add_argument(
        '--config',
        dest='config',
        help='custom configuration properties for the unit tests')
    parser.add_argument(
        '--filter',
        dest='filter',
        help='select only the tests matching the specified regular expression')
    parser.add_argument('--list',
                        dest='list',
                        action='store_true',
                        help='list all tests available tests')
    parser.add_argument('--verbose',
                        dest='verbose',
                        default=2,
                        help='set the verbosity level (i.e 0, 1, 2 or 3)')
    args = parser.parse_args()

    global printLuxCoreLog
    if int(args.verbose) >= 3:
        printLuxCoreLog = True

    # Read the custom configuration file
    if args.config:
        LuxCoreTest.customConfigProps.SetFromFile(args.config)

    # Discover all tests

    propertiesSuite = unittest.TestLoader().discover(
        "pyluxcoreunittests.tests.properties", top_level_dir=".")
    basicSuite = unittest.TestLoader().discover(
        "pyluxcoreunittests.tests.basic", top_level_dir=".")
    lightSuite = unittest.TestLoader().discover(
        "pyluxcoreunittests.tests.lights", top_level_dir=".")
    textureSuite = unittest.TestLoader().discover(
        "pyluxcoreunittests.tests.textures", top_level_dir=".")

    allTests = unittest.TestSuite(
        [propertiesSuite, basicSuite, lightSuite, textureSuite])

    # List the tests if required

    if args.list:
        print("All tests available:")
        l = ListAllTests(allTests)
        count = 0
        for t in l:
            print("  %s" % t)
            count += 1
        print("%d test(s) listed" % count)
        return

    # Filter the tests if required

    if args.filter:
        print("Filtering tests by: %s" % args.filter)
        allTests = unittest.TestSuite(FilterTests(args.filter, allTests))

    unittest.TextTestRunner(verbosity=int(args.verbose)).run(allTests)
Beispiel #17
0
from time import sleep
import array
import os
from pathlib import Path
import sys
# Put your luxcore python module path here.
sys.path.append('/home/graphics/Programs/LuxCore-opencl/')
#sys.path.append('/home/graphics/Programs/LuxCore/build/lib/')
import pyluxcore
print('Using luxcorerender version ' + pyluxcore.Version())

mesh_directory = "screens/" # Where are the mesh files located to render?
output_dir = "renders/" # Where to save rendering related files and frames.

def build_scene(fluid_mesh):
    scene = pyluxcore.Scene()
    props = pyluxcore.Properties()

    props.SetFromString("""
        scene.camera.type = "perspective"
        scene.camera.lookat.orig = 0.5 -2.0 1.0
        scene.camera.lookat.target = 0.5 0.5 0.4
        scene.camera.fieldofview = 35
        ################################################################################
        scene.materials.fluid.type = glass
        #scene.materials.fluid.kd = 1. 0.824176 0.549451
        scene.materials.fluid.kr = 1.0 1.0 1.0
        scene.materials.fluid.kt = 1.0 1.0 1.0
        scene.materials.fluid.interiorior = 1.333
        scene.materials.fluid.exteriorior = 1.0
        scene.materials.fluid.photongi.enable = 1
Beispiel #18
0
def main():
    logger.info("LuxCore Unit tests")

    try:
        pyluxcore.Init(LuxCoreLogHandler)
        logger.info("LuxCore %s" % pyluxcore.Version())
        logger.info("LuxCore has OpenCL: %r" %
                    pyluxcoreunittests.tests.utils.LuxCoreHasOpenCL())

        # Parse command line options

        parser = argparse.ArgumentParser(
            description='Runs LuxCore test suite.')
        parser.add_argument(
            '--config',
            help='custom configuration properties for the unit tests')
        parser.add_argument(
            '--resume',
            action='store_true',
            help='resume a previously interrupted test session')
        parser.add_argument(
            '--filter',
            help=
            'select only the tests matching the specified regular expression')
        parser.add_argument('--list',
                            action='store_true',
                            help='list all available tests')
        parser.add_argument('--subset',
                            action='store_true',
                            help='list all tests available tests')
        parser.add_argument('--verbose',
                            default=2,
                            help='set the verbosity level (i.e 0, 1, 2 or 3)')
        args = parser.parse_args()

        global printLuxCoreLog
        if int(args.verbose) >= 3:
            printLuxCoreLog = True

        if not args.resume:
            # Delete all images in the images directory
            logger.info("Deleting all images...")
            folder = "images"
            for f in [
                    png for png in os.listdir(folder) if png.endswith(".png")
            ]:
                filePath = os.path.join(folder, f)
                os.unlink(filePath)
            logger.info("ok")

        # Read the custom configuration file
        if args.config:
            LuxCoreTest.customConfigProps.SetFromFile(args.config)

        # Mostly used to save time (to not hit the cap) on Travis CI
        pyluxcoreunittests.tests.utils.USE_SUBSET = args.subset

        # Discover all tests

        propertiesSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.properties", top_level_dir=".")
        basicSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.basic", top_level_dir=".")
        lightSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.lights", top_level_dir=".")
        materialSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.materials", top_level_dir=".")
        textureSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.textures", top_level_dir=".")
        sceneSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.scene", top_level_dir=".")
        haltSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.halt", top_level_dir=".")
        serializationSuite = unittest.TestLoader().discover(
            "pyluxcoreunittests.tests.serialization", top_level_dir=".")

        allTests = unittest.TestSuite([
            propertiesSuite, basicSuite, lightSuite, materialSuite,
            textureSuite, sceneSuite, haltSuite, serializationSuite
        ])

        # List the tests if required

        if args.list:
            logger.info("All tests available:")
            l = ListAllTests(allTests)
            count = 0
            for t in l:
                logger.info("#%d  %s" % (count, t))
                count += 1
            logger.info("%d test(s) listed" % count)
            return

        # Filter the tests if required

        if args.filter:
            logger.info("Filtering tests by: %s" % args.filter)
            allTests = unittest.TestSuite(FilterTests(args.filter, allTests))

        # Skips the already done tests if required

        doneCount = 0
        if args.resume:
            with open("totaltestsdone.txt", "r") as f:
                doneCount = int(f.readlines()[0])
            logger.info("Tests already done: %d" % doneCount)

            TailTestsImpl_index = 0
            allTests = unittest.TestSuite(TailTests(doneCount, allTests))

        # To catch Ctrl-C
        unittest.installHandler()

        results = unittest.TextTestRunner(resultclass=TimeLoggingTestResult,
                                          stream=StreamToLogger(),
                                          verbosity=int(
                                              args.verbose)).run(allTests)

        # Print 10 slower tests (a tool to keep the total execution time in check)
        logger.info("20 slower tests execution times:")
        testTimes = results.getTestTimes()
        for t in sorted(testTimes, key=testTimes.get, reverse=True)[:20]:
            logger.info(" %s => %f secs", t, testTimes[t])

        # Save the number of tests run for a potential later resume
        with open("totaltestsdone.txt", "w") as f:
            f.write(str(results.testsRun + doneCount) + "\n")

        sys.exit(not results.wasSuccessful())
    finally:
        pyluxcore.SetLogHandler(None)
Beispiel #19
0
    def NodeThread(self):
        logger.info("Node thread started")

        # Connect with the node
        nodeSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            # Use a timepout of 10 seconds
            nodeSocket.settimeout(10)
            nodeSocket.connect(
                (self.renderFarmNode.address, self.renderFarmNode.port))
            nodeSocket.settimeout(None)

            #-------------------------------------------------------------------
            # Send the LuxCore version (they must match)
            #-------------------------------------------------------------------

            socketutils.SendLine(nodeSocket, pyluxcore.Version())
            socketutils.RecvOk(nodeSocket)
            logger.info("Remote node has the same pyluxcore version")

            #-------------------------------------------------------------------
            # Send the RenderConfig serialized file
            #-------------------------------------------------------------------

            socketutils.SendFile(nodeSocket,
                                 self.jobSingleImage.GetRenderConfigFileName())

            #-------------------------------------------------------------------
            # Send the seed
            #-------------------------------------------------------------------

            logger.info("Sending seed: " + self.seed)
            socketutils.SendLine(nodeSocket, self.seed)

            #-------------------------------------------------------------------
            # Receive the rendering start
            #-------------------------------------------------------------------

            logger.info("Waiting for node rendering start")
            result = socketutils.RecvLine(nodeSocket)
            if (result != "RENDERING_STARTED"):
                logger.info(result)
                raise RuntimeError(
                    "Error while waiting for the rendering start")
            logger.info("Node rendering started")

            #-------------------------------------------------------------------
            # Receive stats and film
            #-------------------------------------------------------------------

            lastFilmUpdate = time.time()
            with self.eventCondition:
                while True:
                    timeTofilmUpdate = self.jobSingleImage.filmUpdatePeriod - (
                        time.time() - lastFilmUpdate)

                    continueLoop = False
                    if ((timeTofilmUpdate <= 0.0) or self.eventUpdateFilm):
                        # Time to request a film update
                        socketutils.SendLine(nodeSocket, "GET_FILM")
                        # TODO add SafeSave
                        socketutils.RecvFile(nodeSocket,
                                             self.GetNodeFilmFileName())
                        lastFilmUpdate = time.time()
                        self.eventUpdateFilm = False
                        # Check the stop condition before to continue the loop
                        continueLoop = True

                    if (self.eventStop):
                        logger.info("Waiting for node rendering stop")
                        socketutils.SendLine(nodeSocket, "DONE")
                        socketutils.RecvOk(nodeSocket)
                        break

                    if continueLoop:
                        continue

                    # Print some rendering node statistic
                    socketutils.SendLine(nodeSocket, "GET_STATS")
                    result = socketutils.RecvLine(nodeSocket)
                    if (result.startswith("ERROR")):
                        logger.info(result)
                        raise RuntimeError(
                            "Error while waiting for the rendering statistics")
                    logger.info("Node rendering statistics: " + result)

                    self.eventCondition.wait(
                        min(timeTofilmUpdate, self.jobSingleImage.statsPeriod))
        except Exception as e:
            logger.exception(e)
            self.jobSingleImage.renderFarm.SetNodeState(
                self.renderFarmNode, renderfarm.NodeState.ERROR)
        else:
            self.jobSingleImage.renderFarm.SetNodeState(
                self.renderFarmNode, renderfarm.NodeState.FREE)
        finally:
            try:
                nodeSocket.shutdown(socket.SHUT_RDWR)
            except:
                pass

            try:
                nodeSocket.close()
            except:
                pass

        logger.info("Node thread done")