diff --git a/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py b/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py index 296116caae..d69cc6f0a1 100644 --- a/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py +++ b/openpype/hosts/maya/plugins/create/create_unreal_staticmesh.py @@ -35,11 +35,21 @@ class CreateUnrealStaticMesh(plugin.Creator): with lib.undo_chunk(): instance = super(CreateUnrealStaticMesh, self).process() content = cmds.sets(instance, query=True) - geometry = cmds.sets(name="geometry_SET", empty=True) - collisions = cmds.sets(name="collisions_SET", empty=True) - cmds.sets([geometry, collisions], forceElement=instance) - for node in content: - if [n for n in self.collision_prefixes if node.startswith(n)]: - cmds.sets(node, forceElement=collisions) - else: - cmds.sets(node, forceElement=geometry) + + # empty set and process its former content + cmds.sets(content, rm=instance) + geometry_set = cmds.sets(name="geometry_SET", empty=True) + collisions_set = cmds.sets(name="collisions_SET", empty=True) + + cmds.sets([geometry_set, collisions_set], forceElement=instance) + + members = cmds.ls(content, long=True) or [] + children = cmds.listRelatives(members, allDescendents=True, + fullPath=True) or [] + children = cmds.ls(children, type="transform") + for node in children: + if cmds.listRelatives(node, type="shape"): + if [n for n in self.collision_prefixes if node.startswith(n)]: + cmds.sets(node, forceElement=collisions_set) + else: + cmds.sets(node, forceElement=geometry_set) diff --git a/openpype/hosts/maya/plugins/publish/clean_nodes.py b/openpype/hosts/maya/plugins/publish/clean_nodes.py index cd3613cc4f..03995cdabe 100644 --- a/openpype/hosts/maya/plugins/publish/clean_nodes.py +++ b/openpype/hosts/maya/plugins/publish/clean_nodes.py @@ -18,9 +18,14 @@ class CleanNodesUp(pyblish.api.InstancePlugin): def process(self, instance): if not instance.data.get("cleanNodes"): - self.log.info("nothing to clean") + self.log.info("Nothing to clean.") + return - nodes_to_clean = instance.data.pop("cleanNodes") + nodes_to_clean = instance.data.pop("cleanNodes", []) self.log.info("Removing {} nodes".format(len(nodes_to_clean))) for node in nodes_to_clean: - cmds.remove(node) + try: + cmds.delete(node) + except ValueError: + # object might be already deleted, don't complain about it + pass diff --git a/openpype/hosts/maya/plugins/publish/collect_unreal_staticmesh.py b/openpype/hosts/maya/plugins/publish/collect_unreal_staticmesh.py index ad6398041b..b1fb0542f2 100644 --- a/openpype/hosts/maya/plugins/publish/collect_unreal_staticmesh.py +++ b/openpype/hosts/maya/plugins/publish/collect_unreal_staticmesh.py @@ -19,7 +19,7 @@ class CollectUnrealStaticMesh(pyblish.api.InstancePlugin): # add fbx family to trigger fbx extractor instance.data["families"].append("fbx") # take the name from instance (without the `S_` prefix) - instance.data["staticMeshCombinedName"] = instance.name[1:] + instance.data["staticMeshCombinedName"] = instance.name[2:] geometry_set = [i for i in instance if i == "geometry_SET"] instance.data["membersToCombine"] = cmds.sets( diff --git a/openpype/hosts/maya/plugins/publish/extract_unreal_staticmesh.py b/openpype/hosts/maya/plugins/publish/extract_unreal_staticmesh.py index fd9cf69612..7867952de6 100644 --- a/openpype/hosts/maya/plugins/publish/extract_unreal_staticmesh.py +++ b/openpype/hosts/maya/plugins/publish/extract_unreal_staticmesh.py @@ -3,6 +3,7 @@ import openpype.api import pyblish.api from maya import cmds # noqa +from uuid import uuid4 class ExtractUnrealStaticMesh(openpype.api.Extractor): @@ -16,13 +17,27 @@ class ExtractUnrealStaticMesh(openpype.api.Extractor): to_combine = instance.data.get("membersToCombine") static_mesh_name = instance.data.get("staticMeshCombinedName") self.log.info( - "merging {] into {}".format( - "+ ".join(to_combine), static_mesh_name)) + "merging {} into {}".format( + " + ".join(to_combine), static_mesh_name)) + duplicates = cmds.duplicate(to_combine, ic=True) cmds.polyUnite( - *to_combine, - n=static_mesh_name) + *duplicates, + n=static_mesh_name, ch=False) + + collision_duplicates = cmds.duplicate( + instance.data.get("collisionMembers"), ic=True) + cmds.parent(collision_duplicates, a=True, w=True) + instance.data["collisionMembers"] = collision_duplicates + + self.log.info( + "collision members: {}".format(instance.data["collisionMembers"])) if not instance.data.get("cleanNodes"): instance.data["cleanNodes"] = [] instance.data["cleanNodes"].append(static_mesh_name) + instance.data["cleanNodes"] += duplicates + instance.data["cleanNodes"] += collision_duplicates + + instance.data["setMembers"] = [static_mesh_name] + instance.data["setMembers"] += instance.data["collisionMembers"] diff --git a/openpype/hosts/maya/plugins/publish/validate_assembly_name.py b/openpype/hosts/maya/plugins/publish/validate_assembly_name.py index 8f7a3dfaf9..41349553fc 100644 --- a/openpype/hosts/maya/plugins/publish/validate_assembly_name.py +++ b/openpype/hosts/maya/plugins/publish/validate_assembly_name.py @@ -30,7 +30,7 @@ class ValidateAssemblyName(pyblish.api.InstancePlugin): descendants = cmds.listRelatives(content_instance, allDescendents=True, fullPath=True) or [] - descendants = cmds.ls(descendants, noIntermediate=True, long=True) + descendants = cmds.ls(descendants, noIntermediate=True, type="transform") content_instance = list(set(content_instance + descendants)) assemblies = cmds.ls(content_instance, assemblies=True, long=True) diff --git a/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py b/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py index c5aa14ec0c..901a2ec75e 100644 --- a/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py +++ b/openpype/hosts/maya/plugins/publish/validate_unreal_staticmesh_naming.py @@ -4,6 +4,8 @@ from maya import cmds # noqa import pyblish.api import openpype.api import openpype.hosts.maya.api.action +from avalon.api import Session +from openpype.api import get_project_settings import re @@ -15,14 +17,14 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin): in Settings UI. This plugin also validates other types of meshes - collision meshes: - UBX_[RenderMeshName]_##: + UBX_[RenderMeshName]*: Boxes are created with the Box objects type in Max or with the Cube polygonal primitive in Maya. You cannot move the vertices around or deform it in any way to make it something other than a rectangular prism, or else it will not work. - UCP_[RenderMeshName]_##: + UCP_[RenderMeshName]*: Capsules are created with the Capsule object type. The capsule does not need to have many segments (8 is a good number) at all because it is @@ -30,7 +32,7 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin): boxes, you should not move the individual vertices around. - USP_[RenderMeshName]_##: + USP_[RenderMeshName]*: Spheres are created with the Sphere object type. The sphere does not need to have many segments (8 is a good number) at all because it is @@ -38,7 +40,7 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin): boxes, you should not move the individual vertices around. - UCX_[RenderMeshName]_##: + UCX_[RenderMeshName]*: Convex objects can be any completely closed convex 3D shape. For example, a box can also be a convex object @@ -53,14 +55,23 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin): families = ["unrealStaticMesh"] label = "Unreal StaticMesh Name" actions = [openpype.hosts.maya.api.action.SelectInvalidAction] - regex_mesh = r"(?P.*)_(\d{2})" - regex_collision = r"_(?P.*)_(\d{2})" + regex_mesh = r"(?P.*))" + regex_collision = r"(?P.*)" @classmethod def get_invalid(cls, instance): invalid = [] + project_settings = get_project_settings(Session["AVALON_PROJECT"]) + collision_prefixes = ( + project_settings + ["maya"] + ["create"] + ["CreateUnrealStaticMesh"] + ["collision_prefixes"] + ) + combined_geometry_name = instance.data.get( "staticMeshCombinedName", None) if cls.validate_mesh: @@ -81,10 +92,11 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin): return False regex_collision = "{}{}".format( - "({})_".format( - "|".join("(0}".format(p) for p in cls.collision_prefixes) + "(?P({}))_".format( + "|".join("{0}".format(p) for p in collision_prefixes) ) or "", cls.regex_collision ) + cl_r = re.compile(regex_collision) for obj in collision_set: @@ -92,20 +104,29 @@ class ValidateUnrealStaticMeshName(pyblish.api.InstancePlugin): if not cl_m: cls.log.error("{} is invalid".format(obj)) invalid.append(obj) - elif cl_m.group("renderName") != combined_geometry_name: - cls.log.error( - "Collision object name doesn't match" - "static mesh name: {} != {}".format( - cl_m.group("renderName"), - combined_geometry_name) + else: + expected_collision = "{}_{}".format( + cl_m.group("prefix"), + combined_geometry_name ) - invalid.append(obj) + + if not obj.startswith(expected_collision): + + cls.log.error( + "Collision object name doesn't match " + "static mesh name" + ) + cls.log.error("{}_{} != {}_{}".format( + cl_m.group("prefix"), + cl_m.group("renderName"), + cl_m.group("prefix"), + combined_geometry_name, + )) + invalid.append(obj) return invalid def process(self, instance): - # todo: load prefixes from creator settings. - if not self.validate_mesh and not self.validate_collision: self.log.info("Validation of both mesh and collision names" "is disabled.") diff --git a/openpype/plugins/publish/integrate_new.py b/openpype/plugins/publish/integrate_new.py index cec2e470b3..bf214d9139 100644 --- a/openpype/plugins/publish/integrate_new.py +++ b/openpype/plugins/publish/integrate_new.py @@ -389,6 +389,7 @@ class IntegrateAssetNew(pyblish.api.InstancePlugin): repre["ext"] = ext template_data["ext"] = ext + self.log.info(template_name) template = os.path.normpath( anatomy.templates[template_name]["path"])