def test_conversion(projectdir): config = pman.get_config() config.layers['project']['general'] = { 'material_mode': 'pbr', } config.write() config = pman.get_config() assert config['blend2bam']['material_mode'] == 'pbr'
def create_render_manager(base, config=None): if config is None: try: config = pman.get_config() except pman.NoConfigError: print( "RenderManager: Could not find pman config, falling back to basic plugin" ) config = None renderplugin = config['general']['render_plugin'] if config else '' if not renderplugin: return BasicRenderManager(base) rppath = pman.get_abs_path(config, renderplugin) maindir = os.path.dirname( pman.get_abs_path(config, config['run']['main_file'])) rppath = os.path.splitext(os.path.relpath(rppath, maindir))[0] module_parts = rppath.split(os.sep) modname = '.'.join(module_parts) print(modname) try: mod = pman.load_module(modname, config) except ImportError: print( "RenderManager: Could not find module ({}), falling back to basic plugin" .format(modname)) return BasicRenderManager(base) return mod.get_plugin()(base)
def update_rman(self): try: pman_conf = pman.get_config(self.workingdir) except pman.NoConfigError: pman_conf = None self.renderer = pman.create_renderer(self, pman_conf)
def __init__(self): filedir = os.path.dirname( bpy.data.filepath) if bpy.data.filepath else os.getcwd() try: config = pman.get_config(filedir) user_config = pman.get_user_config( config['internal']['projectdir']) except pman.NoConfigError: config = None user_config = None self._tmpfnames = set() self.update_queue = queue.Queue() if user_config is not None and user_config['python']['in_venv']: pyprog = 'python' else: pyprog = pman.get_python_program(config) scriptloc = os.path.join(os.path.dirname(__file__), 'processor_app.py') with multiprocessing.connection.Listener() as listener: args = [ pyprog, scriptloc, filedir, str(listener.address), ] self.proc = subprocess.Popen(args) if self.proc.poll() is None: self.connection = listener.accept() self._running = True self.timer = threading.Thread(target=self._timer_thread) self.timer.start()
def test_conf_override(projectdir): # Check default config = pman.get_config() config_defaults = config.layers['default'] assert config['general']['name'] == config_defaults['general']['name'] # Check that project overrides default project_layer = config.layers['project'] project_layer['general'] = { 'name': 'projectname', 'renderer': 'basic', } assert config['general']['name'] == 'projectname' # Check that user overrides default user_layer = config.layers['user'] user_layer['general'] = { 'name': 'username', } assert config['general']['name'] == 'username' # Check that non-overridden default settings are still intact assert config['build']['asset_dir'] == config_defaults['build'][ 'asset_dir'] # Check that non-overridden project settings are still intact assert config['general']['renderer'] == 'basic'
def execute(self, _context): try: config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) pman.create_project(config['internal']['projectdir'], ['blender']) return {'FINISHED'} except pman.PManException as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'}
def execute(self, _context): try: config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) pman.build(config) return {'FINISHED'} except pman.PManException as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'}
def update_rman(self): try: pman_conf = pman.get_config(self.workingdir) self.renderer = pman.create_renderer(self, pman_conf) except pman.NoConfigError: from pman import basicrenderer # pylint:disable=no-name-in-module print('No configuration found, falling back to basic renderer') self.renderer = basicrenderer.BasicRenderer(self)
def test(_): config = pman.get_config() args = [ pman.get_python_program(), 'setup.py', 'test', ] subprocess.call(args, cwd=config['internal']['projectdir'])
def f(self, value): config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) if conf_type == ConfTypes.path: # Convert from Blender path to pman path value = bpy.path.abspath(value) config[section][field] = pman.get_rel_path(config, value) else: config[section][field] = str(value) #print("SET CONF", section, field, value) pman.write_config(config)
def execute(self, _context): try: config = pman.get_config( os.path.dirname(bpy.data.filepath) if bpy.data. filepath else None) pman.create_project(config['internal']['projectdir'], ['blender']) return {'FINISHED'} except pman.PManException as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'}
def execute(self, _context): try: config = pman.get_config( os.path.dirname(bpy.data.filepath) if bpy.data. filepath else None) pman.build(config) return {'FINISHED'} except pman.PManException as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'}
def execute(self, _context): try: config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) if config['run']['auto_save']: bpy.ops.wm.save_mainfile() pman.run(config) return {'FINISHED'} except pman.PManException as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'}
def test_run_script(projectdir): conf = pman.get_config() scriptloc = 'script.py' outputloc = 'output' with open(scriptloc, 'w') as scriptfile: scriptfile.write(PRINT_VENV_SCRIPT.format(outputloc)) pman.run_script(conf, [scriptloc], cwd=conf['internal']['projectdir']) assert os.path.exists(outputloc) with open(outputloc) as outputfile: assert outputfile.read() == 'True'
def test_run_args(projectdir): with open('main.py', 'w') as main_file: main_file.write(EXTRA_ARGS_MAIN) config = pman.get_config() config['run']['extra_args'] = "--test 'hello world'" config.write() pman.run() with open('tmp', 'r') as tmpfile: assert tmpfile.read() == "['--test', 'hello world']"
def execute(self, _context): try: config = pman.get_config( os.path.dirname(bpy.data.filepath) if bpy.data. filepath else None) if config['run']['auto_save']: bpy.ops.wm.save_mainfile() pman.run(config) return {'FINISHED'} except pman.PManException as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'}
def test_conf_order(projectdir): confloc = pman.ConfigDict.PROJECT_CONFIG_NAME with open(confloc, 'w') as conffile: conffile.write(PROJECT_CONF_DATA) config = pman.get_config() config.layers['project']['run']['main_file'] = 'foo.py' config.write() with open(confloc) as conffile: readdata = conffile.read().strip() assert readdata == EXPECTED_CONF_DATA
def __init__(self): try: config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) except pman.NoConfigError as e: config = None pycmd = pman.get_python_program(config) path = os.path.join(os.path.dirname(__file__), 'processor_app.py') args = [pycmd, path, os.path.dirname(bpy.data.filepath)] super().__init__( processor=ExternalProcessor(args), use_bgr_texture=True )
def execute(self, _context): pman.create_project(self.directory) config = pman.get_config(self.directory) user_config = pman.get_user_config(self.directory) from pman import hooks # pylint:disable=no-name-in-module hooks.create_blender(self.directory, config, user_config) if self.switch_dir: os.chdir(self.directory) update_blender_path() return {'FINISHED'}
def f(self): config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) if conf_type == ConfTypes.string: value = config[section][field] elif conf_type == ConfTypes.path: # Convert from pman path to Blender path value = pman.get_abs_path(config, config[section][field]) value = bpy.path.relpath(value) elif conf_type == ConfTypes.boolean: value = config.getboolean(section, field) else: raise TypeError("Unexpected conf_type {}".format(conf_type)) #print("GET CONF", section, field, value) return value
def __init__(self): if USE_EXTERNAL: try: config = pman.get_config(os.path.dirname(bpy.data.filepath) if bpy.data.filepath else None) except pman.NoConfigError as e: config = None pycmd = pman.get_python_program(config) path = os.path.join(os.path.dirname(__file__), 'processor_app.py') args = [pycmd, path, os.path.dirname(bpy.data.filepath)] super().__init__(processor=ExternalProcessor(args), use_bgr_texture=True) else: if PandaEngine._processor is None: PandaEngine._processor = processor.PandaProcessor() PandaEngine._processor.reset(os.path.dirname(bpy.data.filepath)) self.processor = PandaEngine._processor super().__init__(processor=PandaEngine._processor)
def create_render_manager(base, config=None): if config is None: try: config = pman.get_config() except pman.NoConfigError: print( "RenderManager: Could not find pman config, falling back to basic plugin" ) config = None renderplugin = config.get('general', 'render_plugin') if config else '' if not renderplugin: return BasicRenderManager(base) rppath = pman.get_abs_path(config, renderplugin) maindir = os.path.dirname( pman.get_abs_path(config, config.get('run', 'main_file'))) rppath = os.path.splitext(os.path.relpath(rppath, maindir))[0] module_parts = rppath.split(os.sep) def load_module(modname, modinfo): mod = None try: mod = imp.load_module(modname, *modinfo) finally: if modinfo[0]: modinfo[0].close() return mod if pman.is_frozen(): modname = '.'.join(module_parts) modinfo = imp.find_module(modname) mod = load_module(modname, modinfo) else: mod = None for modname in module_parts: modpath = None if mod is None else mod.__path__ modinfo = imp.find_module(modname, modpath) mod = load_module(modname, modinfo) return mod.get_plugin()(base)
def create_render_manager(base, config=None): if config is None: try: config = pman.get_config() except pman.NoConfigError: print("RenderManager: Could not find pman config, falling back to basic plugin") config = None renderplugin = config.get('general', 'render_plugin') if config else '' if not renderplugin: return BasicRenderManager(base) path = pman.get_abs_path(config, renderplugin) if HAS_SFL: mod = SourceFileLoader("render_plugin", path).load_module() else: mod = imp.load_source("render_plugin", path) return mod.get_plugin()(base)
def __init__(self): if USE_EXTERNAL: try: config = pman.get_config( os.path.dirname(bpy.data.filepath) if bpy.data. filepath else None) except pman.NoConfigError as e: config = None pycmd = pman.get_python_program(config) path = os.path.join(os.path.dirname(__file__), 'processor_app.py') args = [pycmd, path, os.path.dirname(bpy.data.filepath)] super().__init__(processor=ExternalProcessor(args), use_bgr_texture=True) else: if PandaEngine._processor is None: PandaEngine._processor = processor.PandaProcessor() PandaEngine._processor.reset(os.path.dirname(bpy.data.filepath)) self.processor = PandaEngine._processor super().__init__(processor=PandaEngine._processor)
def __init__(self): filedir = os.path.dirname(bpy.data.filepath) if bpy.data.filepath else os.getcwd() try: config = pman.get_config(filedir) user_config = pman.get_user_config(config['internal']['projectdir']) except pman.NoConfigError: config = None user_config = None self._tmpfnames = set() self.update_queue = queue.Queue() if user_config is not None and user_config['python']['in_venv']: pyprog = 'python' else: pyprog = pman.get_python_program(config) scriptloc = os.path.join( os.path.dirname(__file__), 'processor_app.py' ) with multiprocessing.connection.Listener() as listener: args = [ pyprog, scriptloc, filedir, str(listener.address), ] self.proc = subprocess.Popen(args) if self.proc.poll() is None: self.connection = listener.accept() self._running = True self.timer = threading.Thread(target=self._timer_thread) self.timer.start()
def reset(self, workingdir): self.bg = p3d.LVector4(0.0, 0.0, 0.0, 1.0) p3d.get_model_path().clear() pman_conf = None if workingdir: p3d.get_model_path().prepend_directory(workingdir) try: pman_conf = pman.get_config(workingdir) except pman.NoConfigError: pass if self.converter is not None: self.converter.active_scene.remove_node() self.converter = converter.Converter() if self.render is not None: self.render.remove_node self.render = p3d.NodePath('render') rman = pman_conf['general']['render_manager'] if pman_conf else 'basic' self.render_manager = rendermanager.create_render_manager(rman, self)
def update(args): config = pman.get_config() pman.create_project(config['internal']['projectdir'], args.extras)
def main(): parser = argparse.ArgumentParser( description='Tool for building and managing Panda3D applications') parser.add_argument( '--version', action='version', version=f'%(prog)s {pman.__version__}', ) parser.add_argument( '-v', '--verbose', action='store_true', help='enable verbose prints', ) subparsers = parser.add_subparsers(title='commands', ) create_parser = subparsers.add_parser( 'create', help='Create a new project', ) create_parser.add_argument( 'dirname', action='store', nargs='?', default='.', help= 'Directory to create the project in (will be created if it does not exist)', ) create_parser.add_argument( '--extras', action='store', nargs='+', help='Extra creation hooks to run', ) create_parser.set_defaults(func=create) update_parser = subparsers.add_parser( 'update', help='Re-run project creation logic on the project directory') update_parser.add_argument( '--extras', action='store', nargs='+', help='Extra creation hooks to run', ) update_parser.set_defaults(func=update) build_parser = subparsers.add_parser( 'build', help='Build project', ) build_parser.set_defaults(func=build) run_parser = subparsers.add_parser( 'run', help='Run project', ) run_parser.set_defaults(func=run) test_parser = subparsers.add_parser( 'test', help='Run tests', ) test_parser.set_defaults(func=test) dist_parser = subparsers.add_parser( 'dist', help='Create binary distributions and installers') dist_parser.add_argument( '--skip-installers', action='store_true', help='Do not build installers', ) dist_parser.add_argument( '-p', '--platforms', action='store', nargs='+', help='Override list of platforms to build for', ) dist_parser.set_defaults(func=dist) clean_parser = subparsers.add_parser( 'clean', help='Remove built files', ) clean_parser.set_defaults(func=clean) args = parser.parse_args() if not hasattr(args, 'func'): print('A command must be provided\n') parser.print_help() sys.exit(1) if pman.config_exists(): config = pman.get_config() config['general'][ 'verbose'] = args.verbose or config['general']['verbose'] else: config = None args.func(args, config)
def test_run_script(projectdir): conf = pman.get_config() scriptloc = 'script.py' with open(scriptloc, 'w') as scriptfile: scriptfile.write('import sys; sys.exit(0)') pman.run_script(conf, [scriptloc], cwd=conf['internal']['projectdir'])
def test_shim(projectdir): config = pman.get_config() config['general']['renderer'] = 'none' pman.shim.init(None)
def execute(self, _context): filedir = os.path.dirname( bpy.data.filepath) if bpy.data.filepath else os.path.dirname( self.filepath) try: config = pman.get_config(filedir) except pman.NoConfigError as err: config = None if config: user_config = pman.get_user_config( config['internal']['projectdir']) else: user_config = None try: pycmd = pman.get_python_program(config) except pman.CouldNotFindPythonError as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'} use_legacy_mats = (config is None or config['general']['material_mode'] == 'legacy') material_mode = 'legacy' if use_legacy_mats else 'pbr' # Check if we need to convert the file try: if self.skip_up_to_date and os.stat( bpy.data.filepath).st_mtime <= os.stat( self.filepath).st_mtime: print('"{}" is already up-to-date, skipping'.format( self.filepath)) return {'FINISHED'} except FileNotFoundError: # The file doesn't exist, so we cannot skip conversion pass # Create a temporary blend file to convert tmpfname = os.path.join(filedir, '__bp_temp__.blend') bpy.ops.wm.save_as_mainfile(filepath=tmpfname, copy=True) # Now convert the data to bam blend2bam_args = [ '--blender-dir', os.path.dirname(bpy.app.binary_path), '--material-mode', material_mode, ] blend2bam_args += [tmpfname, self.filepath] retval = {'FINISHED'} try: if user_config is not None and user_config['python']['in_venv']: # Use blend2bam from venv pman.run_program(config, ['blend2bam'] + blend2bam_args) else: # Use bundled blend2bam scriptloc = os.path.join(os.path.dirname(__file__), 'blend2bam_wrapper.py') args = [pycmd, scriptloc] + blend2bam_args if subprocess.call(args) != 0: retval = {'CANCELLED'} finally: # Remove the temporary blend file os.remove(tmpfname) return retval
def test_create_renderer(projectdir): conf = pman.get_config() conf['general']['renderer'] = 'none' pman.build() pman.create_renderer(None, conf)
def execute(self, _context): filedir = os.path.dirname(bpy.data.filepath) if bpy.data.filepath else os.path.dirname(self.filepath) try: config = pman.get_config(filedir) except pman.NoConfigError as err: config = None if config: user_config = pman.get_user_config(config['internal']['projectdir']) else: user_config = None try: pycmd = pman.get_python_program(config) except pman.CouldNotFindPythonError as err: self.report({'ERROR'}, str(err)) return {'CANCELLED'} use_legacy_mats = ( config is None or config['general']['material_mode'] == 'legacy' ) material_mode = 'legacy' if use_legacy_mats else 'pbr' # Check if we need to convert the file try: if self.skip_up_to_date and os.stat(bpy.data.filepath).st_mtime <= os.stat(self.filepath).st_mtime: print('"{}" is already up-to-date, skipping'.format(self.filepath)) return {'FINISHED'} except FileNotFoundError: # The file doesn't exist, so we cannot skip conversion pass # Create a temporary blend file to convert tmpfname = os.path.join(filedir, '__bp_temp__.blend') bpy.ops.wm.save_as_mainfile(filepath=tmpfname, copy=True) # Now convert the data to bam blend2bam_args = [ '--blender-dir', os.path.dirname(bpy.app.binary_path), '--material-mode', material_mode, ] blend2bam_args += [ tmpfname, self.filepath ] retval = {'FINISHED'} try: if user_config is not None and user_config['python']['in_venv']: # Use blend2bam from venv pman.run_program(config, ['blend2bam'] + blend2bam_args) else: # Use bundled blend2bam scriptloc = os.path.join( os.path.dirname(__file__), 'blend2bam_wrapper.py' ) args = [ pycmd, scriptloc ] + blend2bam_args if subprocess.call(args) != 0: retval = {'CANCELLED'} finally: # Remove the temporary blend file os.remove(tmpfname) return retval
def test_conf_contains(projectdir): config = pman.get_config() assert 'general' in config assert 'foo' not in config
def __init__(self, workingdir): ShowBase.__init__(self) self.view_lens = p3d.MatrixLens() self.cam = p3d.NodePath(p3d.Camera('view')) self.cam.node().set_lens(self.view_lens) self.cam.node().set_active(True) self.cam.reparent_to(self.render) self.pipe = p3d.GraphicsPipeSelection.get_global_ptr().make_module_pipe('pandagl') self.bg = p3d.LVecBase4(0.0, 0.0, 0.0, 1.0) p3d.get_model_path().prepend_directory(workingdir) self.texture = p3d.Texture() self.win = None self.make_offscreen(1, 1) self.disableMouse() self.setFrameRateMeter(True) self.image_width = 1 self.image_height = 1 self.image_data = struct.pack('=BBB', 0, 0, 0) # Setup conversion logic self.converter = Converter() self.conversion_queue = queue.Queue() def conversion(task): while not self.conversion_queue.empty(): data = self.conversion_queue.get() #print(data) if 'extras' in data and 'view' in data['extras']: viewd = data['extras']['view'] if 'width' in viewd: width = viewd['width'] height = viewd['height'] self.make_offscreen(width, height) if 'projection_matrix' in viewd: proj_mat = self.converter.load_matrix(viewd['projection_matrix']) self.view_lens.set_user_mat(proj_mat) if 'view_matrix' in viewd: view_mat = self.converter.load_matrix(viewd['view_matrix']) # Panda wants an OpenGL model matrix instead of an OpenGL view matrix view_mat.invert_in_place() self.view_lens.set_view_mat(view_mat) self.converter.update(data) bg = self.converter.background_color self.bg = p3d.LVector4(bg[0], bg[1], bg[2], 1) self.view_region.set_clear_color(self.bg) self.converter.active_scene.reparent_to(self.render) #self.render.ls() if self.texture.has_ram_image(): #start = time.perf_counter() self.server.image_lock.acquire() self.image_width = self.texture.get_x_size() self.image_height = self.texture.get_y_size() self.image_data = memoryview(self.texture.get_ram_image_as("BGR")) self.server.image_lock.release() #print('Extern: Updated image data in {}ms'.format((time.perf_counter() - start) * 1000)) #self.texture.write('tex.png') return task.cont self.taskMgr.add(conversion, 'Conversion') # Setup communication with Blender self.server = Server(self.handle_data, self.get_img) if USE_THREAD: self.server.start() def server_mon(task): if not self.server.is_alive(): print('Server thread has terminated, closing program') self.server.destroy() time.sleep(0.1) sys.exit() return task.cont self.taskMgr.add(server_mon, 'Server Monitor') else: def server_task(task): self.server.run() return task.cont self.taskMgr.add(server_task, 'Server Communication') try: pman_conf = pman.get_config(workingdir) except pman.NoConfigError: pman_conf = None self.rendermanager = rendermanager.create_render_manager(self, pman_conf)
def test_conf(tmpdir): open('.pman', 'w').close() conf = pman.get_config() pman.write_config(conf)
def test_conf_read_write(tmpdir): os.chdir(tmpdir.strpath) open('.pman', 'w').close() conf = pman.get_config() pman.write_config(conf)
def test_conf_missing(projectdir): config = pman.get_config() assert config['python'] assert config['blend2bam']