diff --git a/korman/exporter/convert.py b/korman/exporter/convert.py index 149d3ac..b66c96c 100644 --- a/korman/exporter/convert.py +++ b/korman/exporter/convert.py @@ -49,17 +49,12 @@ class Exporter: self.light = rtlight.LightConverter(self) self.sumfile = sumfile.SumFile() - # Step 1: Gather a list of objects that we need to export - # We should do this first so we can sanity check - # and give accurate progress reports - self._collect_objects() - - # Step 2: Create the age info and the pages + # Step 1: Create the age info and the pages self._export_age_info() - # Step 2.9: Ensure that all Plasma Objects are in a valid page - # This creates the default page if it is used - self.mgr.sanity_check_object_pages(self.age_name, self._objects) + # Step 2: Gather a list of objects that we need to export, given what the user has told + # us to export (both in the Age and Object Properties)... fun + self._collect_objects() # Step 3: Export all the things! self._export_scene_objects() @@ -81,9 +76,41 @@ class Exporter: print("\nExported {}.age in {:.2f} seconds".format(self.age_name, end-start)) def _collect_objects(self): + # Grab a naive listing of enabled pages + age = bpy.context.scene.world.plasma_age + pages_enabled = frozenset([page.name for page in age.pages if page.enabled]) + all_pages = frozenset([page.name for page in age.pages]) + + # Because we can have an unnamed or a named default page, we need to see if that is enabled... + for page in age.pages: + if page.seq_suffix == 0: + default_enabled = page.enabled + default_inited = True + break + else: + default_enabled = True + default_inited = False + + # Now we loop through the objects with some considerations: + # - The default page may or may not be defined. If it is, it can be disabled. If not, it + # can only ever be enabled. + # - Don't create the Default page unless it is used (implicit or explicit). It is a failure + # to export a useless file. + # - Any arbitrary page can be disabled, so check our frozenset. + # - Also, someone might have specified an invalid page, so keep track of that. + error = explosions.UndefinedPageError() for obj in bpy.data.objects: if obj.plasma_object.enabled: - self._objects.append(obj) + page = obj.plasma_object.page + if not page and not default_inited: + self.mgr.create_page(self.age_name, "Default", 0) + default_inited = True + + if (default_enabled and not page) or (page in pages_enabled): + self._objects.append(obj) + elif page not in all_pages: + error.add(page, obj.name) + error.raise_if_error() def _export_age_info(self): # Make life slightly easier... @@ -96,7 +123,8 @@ class Exporter: # Create all the pages we need for page in age_info.pages: - mgr.create_page(age_name, page.name, page.seq_suffix) + if page.enabled: + mgr.create_page(age_name, page.name, page.seq_suffix) mgr.create_builtins(age_name, self._op.use_texture_page) def _export_actor(self, so, bo): diff --git a/korman/exporter/explosions.py b/korman/exporter/explosions.py index ec0d53a..bd385e7 100644 --- a/korman/exporter/explosions.py +++ b/korman/exporter/explosions.py @@ -57,6 +57,8 @@ class UndefinedPageError(ExportError): def raise_if_error(self): if self.mistakes: + # Better give them some idea of what happened... + print(repr(self.mistakes)) raise self diff --git a/korman/exporter/manager.py b/korman/exporter/manager.py index 7e64eb1..dd04f7a 100644 --- a/korman/exporter/manager.py +++ b/korman/exporter/manager.py @@ -142,6 +142,11 @@ class ExportManager: location.page = id self._pages[name] = location + # If the page ID is 0, this is the default page... Any page with an empty string name + # is the default, so bookmark it! + if id == 0: + self._pages[""] = location + info = plPageInfo() info.age = age info.page = name @@ -215,28 +220,6 @@ class ExportManager: return True return False - def sanity_check_object_pages(self, age, objects): - """Ensure all objects are in valid pages and create the Default page if used""" - - error = explosions.UndefinedPageError() - for obj in objects: - page = obj.plasma_object.page - if page in self._pages: - # good. keep trying. - continue - elif page == "": - # This object is in the default page... Init that. - for loc in self._pages.values(): - if not loc.page: - self._pages[""] = loc - break - else: - # need to create default page - self._pages[""] = self.create_page(age, "Default", 0) - else: - error.add(page, obj.name) - error.raise_if_error() - def save_age(self, path): relpath, ageFile = os.path.split(path) ageName = os.path.splitext(ageFile)[0] diff --git a/korman/operators/op_export.py b/korman/operators/op_export.py index 58e30d8..4d614c2 100644 --- a/korman/operators/op_export.py +++ b/korman/operators/op_export.py @@ -38,10 +38,6 @@ class ExportOperator(bpy.types.Operator): ("pvPots", "Path of the Shell (63.12)", "Targets the most recent offline expansion pack", 1), ("pvMoul", "Myst Online: Uru Live (70)", "Targets the most recent online game", 0)]}), - "save_state": (BoolProperty, {"name": "Save State", - "description": "Saves your age's state to the server for subsequent link ins", - "default": True}), - "use_texture_page": (BoolProperty, {"name": "Use Textures Page", "description": "Exports all textures to a dedicated Textures page", "default": True}), @@ -56,7 +52,6 @@ class ExportOperator(bpy.types.Operator): # The crazy mess we're doing with props on the fly means we have to explicitly draw them :( layout.prop(age, "version") - layout.prop(age, "save_state") layout.prop(age, "use_texture_page") def __getattr__(self, attr): diff --git a/korman/properties/prop_world.py b/korman/properties/prop_world.py index 94e2c60..6716dc9 100644 --- a/korman/properties/prop_world.py +++ b/korman/properties/prop_world.py @@ -106,6 +106,9 @@ class PlasmaPage(bpy.types.PropertyGroup): local_only = BoolProperty(name="Local Only", description="This page should not synchronize with the server", default=False) + enabled = BoolProperty(name="Export Page", + description="Export this page", + default=True) # Implementation details... last_name = StringProperty(description="INTERNAL: Cached page name", diff --git a/korman/ui/ui_world.py b/korman/ui/ui_world.py index 6cbebae..44880d2 100644 --- a/korman/ui/ui_world.py +++ b/korman/ui/ui_world.py @@ -26,6 +26,12 @@ class AgeButtonsPanel: return context.world and context.scene.render.engine == "PLASMA_GAME" +class PlasmaPageList(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_property, index=0, flt_flag=0): + layout.prop(item, "name", text="", emboss=False, icon="BOOKMARKS") + layout.prop(item, "enabled", text="") + + class PlasmaAgePanel(AgeButtonsPanel, bpy.types.Panel): bl_label = "Plasma Age" @@ -35,7 +41,7 @@ class PlasmaAgePanel(AgeButtonsPanel, bpy.types.Panel): # We want a list of pages and an editor below that row = layout.row() - row.template_list("UI_UL_list", "pages", age, "pages", age, + row.template_list("PlasmaPageList", "pages", age, "pages", age, "active_page_index", rows=2) col = row.column(align=True) col.operator("world.plasma_page_add", icon="ZOOMIN", text="")