diff --git a/plugins/cinema4d/import_cast.pyp b/plugins/cinema4d/import_cast.pyp index 8cdda42..f0e69de 100644 --- a/plugins/cinema4d/import_cast.pyp +++ b/plugins/cinema4d/import_cast.pyp @@ -1,22 +1,28 @@ import c4d import os -import array +import math import mxutils from c4d import plugins, Vector, Vector4d, CPolygon, gui, BaseObject -PLUGIN_ID = 1062992 PLUGIN_RES_DIR = os.path.join(os.path.dirname(__file__), "res") mxutils.ImportSymbols(PLUGIN_RES_DIR) with mxutils.LocalImportPath(PLUGIN_RES_DIR): - from cast import Cast, CastColor, Model, Animation, Instance, File + from cast import Cast, CastColor, Model, Animation, Instance, Metadata, File, Color -__pluginname__ = "Cast" +__pluginname__ = "Cast (*.cast)" class CastLoader(plugins.SceneLoaderData): + def Init(self, node, isCloneInit): + data = node.GetDataInstance() + data.SetBool(CAST_IMPORT_BIND_SKIN, True) + data.SetBool(CAST_IMPORT_IK_HANDLES, True) + data.SetBool(CAST_IMPORT_CONSTRAINTS, True) + return True + def Identify(self, node, name, probe, size): if "cast" in name[-4:]: return True @@ -27,10 +33,16 @@ class CastLoader(plugins.SceneLoaderData): return c4d.FILEERROR_NONE +def importMetadata(doc, meta): + doc[c4d.DOCUMENT_INFO_AUTHOR] = meta.Author() + doc[c4d.DOCUMENT_INFO_PRGCREATOR_NAME] = meta.Software() + + def importCast(doc, node, path): cast = Cast.load(path) instances = [] + meta = None for root in cast.Roots(): for child in root.ChildrenOfType(Model): @@ -40,8 +52,14 @@ def importCast(doc, node, path): for child in root.ChildrenOfType(Instance): instances.append(child) + # Grab the first defined meta node, if there is one. + meta = meta or root.ChildOfType(Metadata) + if len(instances) > 0: - importInstanceNodes(doc, instances, node, path) + importInstanceNodes(doc, node, instances, path) + + if meta: + importMetadata(doc, meta) def utilityBuildPath(root, asset): @@ -54,32 +72,45 @@ def utilityBuildPath(root, asset): def utilityQuaternionToEuler(tempQuat): quaternion = c4d.Quaternion() - quaternion.w = tempQuat[3] - quaternion.v = Vector(tempQuat[0], tempQuat[1], -tempQuat[2]) + w = tempQuat[3] + ww = 2 * math.acos(w) + sqrt = math.sqrt(1 - w * w) + + if sqrt <= 1e-9: + x = y = z = 0 + else: + x = tempQuat[0] / sqrt + y = tempQuat[1] / sqrt + z = tempQuat[2] / sqrt + + quaternion.SetAxis(Vector(x, y, -z), ww) return c4d.utils.MatrixToHPB(quaternion.GetMatrix(), c4d.ROTATIONORDER_HPB) -def utilityAddTextureMaterialSlots(slotName, texPath, mat, shaderType): - shader = c4d.BaseList2D(c4d.Xbitmap) - shader[c4d.BITMAPSHADER_FILENAME] = texPath - shader.SetName(slotName) +def utilityCreateDefaultMaterial(path, material): + # We don't care much about this material since 99% of users will use the renderers material system + # We just create it basic in a most convinient way to let the user convert it to their prefered renderer. - if slotName == "normal": - mat[c4d.MATERIAL_USE_NORMAL] = True - shader[c4d.BITMAPSHADER_COLORPROFILE] = c4d.BITMAPSHADER_COLORPROFILE_LINEAR + mat = c4d.Material() + mat.SetName(material.Name()) - mat[shaderType] = shader - mat.InsertShader(shader) + mat[c4d.MATERIAL_USE_COLOR] = True + reflLayer = mat.GetReflectionLayerIndex(0) -def utilityAssignMaterialSlots(doc, material, slots, path): switcher = { "albedo": c4d.MATERIAL_COLOR_SHADER, "diffuse": c4d.MATERIAL_COLOR_SHADER, - "normal": c4d.MATERIAL_NORMAL_SHADER + "specular": reflLayer.GetDataID() + c4d.REFLECTION_LAYER_COLOR_TEXTURE, + "normal": c4d.MATERIAL_NORMAL_SHADER, + "roughness": reflLayer.GetDataID() + c4d.REFLECTION_LAYER_MAIN_SHADER_ROUGHNESS, + "gloss": reflLayer.GetDataID() + c4d.REFLECTION_LAYER_MAIN_SHADER_ROUGHNESS, + "emissive": c4d.MATERIAL_LUMINANCE_SHADER, } + # Loop and connect the slots + slots = material.Slots() for slot in slots: connection = slots[slot] if not connection.__class__ is File: @@ -87,29 +118,56 @@ def utilityAssignMaterialSlots(doc, material, slots, path): if not slot in switcher: continue - utilityAddTextureMaterialSlots( - slot, utilityBuildPath(path, connection.Path()), material, switcher[slot]) + if connection.__class__ is File: + shader = c4d.BaseList2D(c4d.Xbitmap) + shader[c4d.BITMAPSHADER_FILENAME] = utilityBuildPath(path, connection.Path()) + shader.SetName(slot) + + if slot in ["metal", "gloss", "roughness", "normal"]: + shader[c4d.BITMAPSHADER_COLORPROFILE] = c4d.BITMAPSHADER_COLORPROFILE_LINEAR + + mat[switcher[slot]] = shader + mat.InsertShader(shader) + elif connection.__class__ is Color: + # Handle color conversion if necessary, Cinema 4D color input is sRGB. + # Not necessary but might work as a guide the users own materials + if connection.ColorSpace() == "linear": + rgba = CastColor.toSRGBFromLinear(connection.Rgba()) + else: + rgba = connection.Rgba() + mat[c4d.MATERIAL_COLOR_COLOR] = Vector(rgba[0], rgba[1], rgba[2]) + else: + continue + if slot == "normal": + mat[c4d.MATERIAL_USE_NORMAL] = True + elif slot in ["gloss", "roughness"]: + # Using it to add a roughness texture, so the user convert the material to the prefered render engine + mat[reflLayer.GetDataID() + c4d.REFLECTION_LAYER_MAIN_DISTRIBUTION] = GGX + elif slot == "emissive": + mat[c4d.MATERIAL_USE_LUMINANCE] = True + mat[c4d.REFLECTION_LAYER_IMPORTED] = True -def importMaterialNode(doc, path, material): - materials = doc.GetMaterials() + return mat - # If you already created the material, ignore this - for mat in materials: + +def importMaterialNode(context, path, material): + # We're checking if the material is already present in the project and import context + doc = c4d.documents.GetActiveDocument() + docMaterials = doc.GetMaterials() + contextMaterials = context.GetMaterials() + for mat in docMaterials + contextMaterials: if mat.GetName() == material.Name(): return mat - materialNew = c4d.BaseMaterial(c4d.Mmaterial) - materialNew.SetName(material.Name()) - - # TODO: Better PBR Support? - utilityAssignMaterialSlots(doc, materialNew, material.Slots(), path) + mat = utilityCreateDefaultMaterial(path, material) - doc.InsertMaterial(materialNew) + # TODO: going through all the updates functions to know which are actually necessary + mat.Message(c4d.MSG_UPDATE) + mat.Update(True, True) + context.InsertMaterial(mat) - materialNew.Message(c4d.MSG_UPDATE) - - return materialNew + return mat def importModelNode(doc, node, model, path): @@ -119,6 +177,8 @@ def importModelNode(doc, node, model, path): # Create a collection for our objects modelNull = BaseObject(c4d.Onull) modelNull.SetName(modelName) + modelNull[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = c4d.ID_BASELIST_ICON_COLORIZE_MODE_CUSTOM + modelNull[c4d.ID_BASELIST_ICON_COLOR] = Vector(0.816, 0.357, 0.259) doc.InsertObject(modelNull) @@ -146,7 +206,7 @@ def importModelNode(doc, node, model, path): newMesh.ResizeObject(vertexCount, facesCount) - for i in range(0, vertexCount, 3): + for i in range(0, len(vertexPositions), 3): newMesh.SetPoint( int(i / 3), Vector(vertexPositions[i], vertexPositions[i + 1], -vertexPositions[i + 2])) @@ -158,22 +218,29 @@ def importModelNode(doc, node, model, path): newMesh.SetPolygon( int(i / 3), CPolygon(faces[i], faces[i + 1], faces[i + 2])) + meshMaterial = mesh.Material() + for i in range(mesh.UVLayerCount()): uvBuffer = mesh.VertexUVLayerBuffer(i) uvTag = c4d.UVWTag(facesCount) - for i in range(0, faceIndicesCount, 3): - uvTag.SetSlow(int(i / 3), - Vector(uvBuffer[faces[i] * 2], - uvBuffer[(faces[i] * 2) + 1], 0), - Vector(uvBuffer[faces[i + 1] * 2], - uvBuffer[(faces[i + 1] * 2) + 1], 0), - Vector(uvBuffer[faces[i + 2] * 2], - uvBuffer[(faces[i + 2] * 2) + 1], 0), + for j in range(0, faceIndicesCount, 3): + uvTag.SetSlow(int(j / 3), + Vector(uvBuffer[faces[j] * 2], + uvBuffer[(faces[j] * 2) + 1], 0), + Vector(uvBuffer[faces[j + 1] * 2], + uvBuffer[(faces[j + 1] * 2) + 1], 0), + Vector(uvBuffer[faces[j + 2] * 2], + uvBuffer[(faces[j + 2] * 2) + 1], 0), Vector(0, 0, 0)) newMesh.InsertTag(uvTag) + if meshMaterial is not None and i < 1: + material_tag = newMesh.MakeTag(c4d.Ttexture) + material_tag[c4d.TEXTURETAG_MATERIAL] = materialArray[meshMaterial.Name()] + material_tag[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_UVW + for i in range(mesh.ColorLayerCount()): vertexColors = mesh.VertexColorLayerBuffer(i) vcTag = c4d.VertexColorTag(vertexCount) @@ -193,18 +260,16 @@ def importModelNode(doc, node, model, path): for i in range(0, faceIndicesCount, 3): vnTag.Set(vnData, int(i / 3), - {"a": Vector(vertexNormals[faces[i] * 3], + {"a": Vector(vertexNormals[faces[i] * 3], vertexNormals[(faces[i] * 3) + 1], -vertexNormals[(faces[i] * 3) + 2]), - "b": Vector(vertexNormals[faces[i + 1] * 3], + "b": Vector(vertexNormals[faces[i + 1] * 3], vertexNormals[(faces[i + 1] * 3) + 1], -vertexNormals[(faces[i + 1] * 3) + 2]), - "c": Vector(vertexNormals[faces[i + 2] * 3], + "c": Vector(vertexNormals[faces[i + 2] * 3], vertexNormals[(faces[i + 2] * 3) + 1], -vertexNormals[(faces[i + 2] * 3) + 2]), - "d": Vector(0, 0, 0)}) - - + "d": Vector(0, 0, 0)}) newMesh.InsertTag(vnTag) @@ -222,6 +287,8 @@ def importModelNode(doc, node, model, path): weightTag = c4d.modules.character.CAWeightTag() + newMesh.InsertTag(weightTag) + for bone in bones.values(): weightTag.AddJoint(bone) @@ -243,28 +310,20 @@ def importModelNode(doc, node, model, path): for x in range(vertexCount): weightTag.SetWeight(weightBoneBuffer[x], x, 1.0) - newMesh.InsertTag(weightTag) - weightTag.Message(c4d.MSG_UPDATE) - meshMaterial = mesh.Material() - if meshMaterial is not None: - material = materialArray[meshMaterial.Name()] - material_tag = newMesh.MakeTag(c4d.Ttexture) - material_tag[c4d.TEXTURETAG_MATERIAL] = material - material_tag[c4d.TEXTURETAG_PROJECTION] = c4d.TEXTURETAG_PROJECTION_UVW - doc.InsertObject(newMesh, parent=modelNull) newMesh.Message(c4d.MSG_UPDATE) if node[CAST_IMPORT_IK_HANDLES]: - importSkeletonIKNode(doc, modelNull, model.Skeleton(), bones) + importSkeletonIKNode(model.Skeleton(), bones) if node[CAST_IMPORT_CONSTRAINTS]: importSkeletonConstraintNode(model.Skeleton(), bones) # TODO: Does this do anything? c4d.EventAdd() + modelNull.Message(c4d.MSG_UPDATE) return modelNull @@ -274,10 +333,13 @@ def importSkeletonConstraintNode(skeleton, bones): return for constraint in skeleton.Constraints(): - constraintBone = bones[constraint.ConstraintBone().Hash()] - targetBone = bones[constraint.TargetBone().Hash()] + constraintBone = bones[constraint.ConstraintBone().Name()] + targetBone = bones[constraint.TargetBone().Name()] type = constraint.ConstraintType() + customOffset = constraint.CustomOffset() + maintainOffset = constraint.MaintainOffset() + weight = constraint.Weight() # C4D's constraint system is a bit worse than Blender's constraintTag = c4d.BaseTag(c4d.Tcaconstraint) @@ -300,12 +362,16 @@ def importSkeletonConstraintNode(skeleton, bones): constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_CONSTRAIN_R_Y] = False constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_CONSTRAIN_R_Z] = False - constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_MAINTAIN] = constraint.MaintainOffset() + constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_MAINTAIN] = maintainOffset + constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_TWEIGHT] = weight if type == "pt": constraintTag[CONSTRAIN_POS] = True constraintTag[CONSTRAINT_TARGET] = targetBone constraintTag[c4d.ID_CA_CONSTRAINT_TAG_LOCAL_P] = True + + if customOffset: + constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_P_OFFSET] = Vector(customOffset) if not constraint.SkipX(): constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_CONSTRAIN_P_X] = True if not constraint.SkipY(): @@ -316,6 +382,9 @@ def importSkeletonConstraintNode(skeleton, bones): constraintTag[CONSTRAIN_SCALE] = True constraintTag[CONSTRAINT_TARGET] = targetBone constraintTag[c4d.ID_CA_CONSTRAINT_TAG_LOCAL_S] = True + + if customOffset: + constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_S_OFFSET] = Vector(customOffset) if not constraint.SkipX(): constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_CONSTRAIN_S_X] = True if not constraint.SkipY(): @@ -326,6 +395,9 @@ def importSkeletonConstraintNode(skeleton, bones): constraintTag[CONSTRAIN_ROT] = True constraintTag[CONSTRAINT_TARGET] = targetBone constraintTag[c4d.ID_CA_CONSTRAINT_TAG_LOCAL_R] = True + + if customOffset: + constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_R_OFFSET] = Vector(customOffset) if not constraint.SkipX(): constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR_CONSTRAIN_R_X] = True if not constraint.SkipY(): @@ -339,42 +411,55 @@ def importSkeletonConstraintNode(skeleton, bones): constraintTag[c4d.ID_BASELIST_NAME] = constraint.Name() -def importSkeletonIKNode(doc, modelNull, skeleton, bones): +def importSkeletonIKNode(skeleton, bones): if skeleton is None or not skeleton.IKHandles(): return - ikParentNull = BaseObject(c4d.Onull) - ikParentNull.SetName("IK_Handles") - doc.InsertObject(ikParentNull, modelNull) for handle in skeleton.IKHandles(): - startBone = bones[handle.StartBone().Hash()] - endBone = bones[handle.EndBone().Hash()] + startBone = bones[handle.StartBone().Name()] + endBone = bones[handle.EndBone().Name()] + targetBone = bones[handle.TargetBone().Name()] - ikTargetNull = BaseObject(c4d.Onull) - ikTargetNull.SetName(endBone.GetName() + "_IK") - ikTargetNull.SetMg(endBone.GetMg()) - ikTargetNull.SetAbsRot(Vector(0, 0, 0)) - doc.InsertObject(ikTargetNull, ikParentNull) + constraintTag = c4d.BaseTag(c4d.Tcaconstraint) + endBone.InsertTag(constraintTag) + constraintTag[c4d.ID_CA_CONSTRAINT_TAG_PSR] = True + constraintTag[CONSTRAINT_TARGET] = targetBone ikTag = c4d.BaseTag(IK_TAG) ikTag[c4d.ID_CA_IK_TAG_SOLVER] = 2 ikTag[c4d.ID_CA_IK_TAG_TIP] = endBone - ikTag[c4d.ID_CA_IK_TAG_TARGET] = ikTargetNull + ikTag[c4d.ID_CA_IK_TAG_TARGET] = targetBone + startBone.InsertTag(ikTag) poleVectorBone = handle.PoleVectorBone() if poleVectorBone is not None: - poleVector = bones[poleVectorBone.Hash()] - ikTag[c4d.ID_CA_IK_TAG_POLE] = poleVector - ikTag[c4d.ID_CA_IK_TAG_POLE_AXIS] = c4d.ID_CA_IK_TAG_POLE_AXIS_X - ikTag[c4d.ID_CA_IK_TAG_POLE_TWIST] = poleVector[c4d.ID_BASEOBJECT_REL_ROTATION, c4d.VECTOR_X] + # Changing the IK solver from 3D to 2D to activate the pole input + ikTag[c4d.ID_CA_IK_TAG_SOLVER] = 1 + ikTag[c4d.ID_CA_IK_TAG_POLE] = bones[poleVectorBone.Name()] + - # TODO: This shouldn't need emulation. poleBone = handle.PoleBone() if poleBone is not None: - # Warn until we figure out how to emulate this effectively. - gui.MessageDialog(text="Unable to setup %s fully due to Cinema 4D not supporting pole (twist) bones." % - poleBone.Name(), type=c4d.GEMB_ICONEXCLAMATION) - startBone.InsertTag(ikTag) + poleBone = bones[poleBone.Name()] + xpressoTag = c4d.BaseTag(c4d.Texpresso) + startBone.InsertTag(xpressoTag) + + gvNodeMaster = xpressoTag.GetNodeMaster() + poleNode = gvNodeMaster.CreateNode(parent = gvNodeMaster.GetRoot(), + id = c4d.ID_OPERATOR_OBJECT, + x = 100, + y = 200 ) + poleNode[c4d.GV_OBJECT_OBJECT_ID] = poleBone + poleRotYPort = poleNode.AddPort(c4d.GV_PORT_OUTPUT, [c4d.ID_BASEOBJECT_REL_ROTATION, c4d.VECTOR_Y]) + + twistNode = gvNodeMaster.CreateNode(parent = gvNodeMaster.GetRoot(), + id = c4d.ID_OPERATOR_OBJECT, + x = 400, + y = 200 ) + twistNode[c4d.GV_OBJECT_OBJECT_ID] = ikTag + twistInPort = twistNode.AddPort(c4d.GV_PORT_INPUT, c4d.ID_CA_IK_TAG_POLE_TWIST) + + poleRotYPort.Connect(twistInPort) def importSkeletonNode(modelNull, skeleton): @@ -383,7 +468,7 @@ def importSkeletonNode(modelNull, skeleton): bones = skeleton.Bones() handles = [None] * len(bones) - boneIndexes = {} + boneNames = {} for i, bone in enumerate(bones): newBone = BaseObject(c4d.Ojoint) @@ -402,7 +487,7 @@ def importSkeletonNode(modelNull, skeleton): newBone.SetAbsScale(scale) handles[i] = newBone - boneIndexes[bone.Hash()] = newBone + boneNames[bone.Name()] = newBone for i, bone in enumerate(bones): if bone.ParentIndex() > -1: @@ -410,7 +495,7 @@ def importSkeletonNode(modelNull, skeleton): else: handles[i].InsertUnder(modelNull) - return boneIndexes + return boneNames def importAnimationNode(): @@ -418,7 +503,7 @@ def importAnimationNode(): text="Animations are currently not supported.", type=c4d.GEMB_ICONSTOP) -def importInstanceNodes(doc, nodes, node, path): +def importInstanceNodes(doc, node, instanceNodes, path): rootPath = c4d.storage.LoadDialog( title='Select the root directory where instance scenes are located', flags=2) @@ -426,8 +511,9 @@ def importInstanceNodes(doc, nodes, node, path): return gui.MessageDialog(text="Unable to import instances without a root directory!", type=c4d.GEMB_ICONSTOP) uniqueInstances = {} + instanceImportError = False - for instance in nodes: + for instance in instanceNodes: refs = os.path.join(rootPath, instance.ReferenceFile().Path()) if refs in uniqueInstances: @@ -440,6 +526,8 @@ def importInstanceNodes(doc, nodes, node, path): # Create a collection for our objects rootNull = BaseObject(c4d.Onull) rootNull.SetName(name) + rootNull[c4d.ID_BASELIST_ICON_COLORIZE_MODE] = c4d.ID_BASELIST_ICON_COLORIZE_MODE_CUSTOM + rootNull[c4d.ID_BASELIST_ICON_COLOR] = Vector(0.816, 0.357, 0.259) doc.InsertObject(rootNull) @@ -466,6 +554,7 @@ def importInstanceNodes(doc, nodes, node, path): modelNull.InsertUnder(sceneNull) except: print("Failed to import instance: %s" % instancePath) + instanceImportError = True continue for instance in instances: @@ -478,8 +567,7 @@ def importInstanceNodes(doc, nodes, node, path): tX, tY, tZ = instance.Position() translation = Vector(tX, tY, -tZ) - tempQuat = instance.Rotation() - rotation = utilityQuaternionToEuler(tempQuat) + rotation = utilityQuaternionToEuler(instance.Rotation()) scaleTuple = instance.Scale() or (1.0, 1.0, 1.0) scale = Vector(scaleTuple[0], scaleTuple[1], scaleTuple[2]) @@ -490,9 +578,12 @@ def importInstanceNodes(doc, nodes, node, path): newInstance.SetReferenceObject(modelNull) + if instanceImportError: + gui.MessageDialog(text="Some instances failed to import.\nCheck the console for more details. ", type=c4d.GEMB_ICONEXCLAMATION) + if __name__ == '__main__': - reg = plugins.RegisterSceneLoaderPlugin(id=PLUGIN_ID, + reg = plugins.RegisterSceneLoaderPlugin(id=SCENE_LOADER_PLUGIN_ID, str=__pluginname__, info=0, g=CastLoader, diff --git a/plugins/cinema4d/res/c4d_symbols.h b/plugins/cinema4d/res/c4d_symbols.h index 45f90ed..e400190 100644 --- a/plugins/cinema4d/res/c4d_symbols.h +++ b/plugins/cinema4d/res/c4d_symbols.h @@ -1,7 +1,7 @@ enum { - PLUGIN_ID = 1062992, - + SCENE_LOADER_PLUGIN_ID = 1062992, + CONSTRAINT_TAG = 1019364, CONSTRAINT_TARGET = 10001, CONSTRAIN_POS = 10005, @@ -9,5 +9,7 @@ enum CONSTRAIN_ROT = 10007, IK_TAG = 1019561, - POLE_AXIS_X = 1 + POLE_AXIS_X = 1, + + GGX = 3 }; diff --git a/plugins/cinema4d/res/description/fcastloader.h b/plugins/cinema4d/res/description/fcastloader.h index 06fd479..f402148 100644 --- a/plugins/cinema4d/res/description/fcastloader.h +++ b/plugins/cinema4d/res/description/fcastloader.h @@ -4,9 +4,9 @@ enum { CAST_LOADER = 10000, - CAST_IMPORT_CONSTRAINTS, - CAST_IMPORT_IK_HANDLES, - CAST_IMPORT_BIND_SKIN, + CAST_IMPORT_CONSTRAINTS = 10001, + CAST_IMPORT_IK_HANDLES = 10002, + CAST_IMPORT_BIND_SKIN = 10003, CAST_IMPORT_GROUP }; #endif diff --git a/plugins/cinema4d/res/description/fcastloader.res b/plugins/cinema4d/res/description/fcastloader.res index d8178ae..4d9734e 100644 --- a/plugins/cinema4d/res/description/fcastloader.res +++ b/plugins/cinema4d/res/description/fcastloader.res @@ -7,8 +7,8 @@ CONTAINER fcastloader { DEFAULT 1; - BOOL CAST_IMPORT_BIND_SKIN {} - BOOL CAST_IMPORT_IK_HANDLES {} - BOOL CAST_IMPORT_CONSTRAINTS {} + BOOL CAST_IMPORT_BIND_SKIN { } + BOOL CAST_IMPORT_IK_HANDLES { } + BOOL CAST_IMPORT_CONSTRAINTS { } } } \ No newline at end of file diff --git a/plugins/cinema4d/res/strings_us/description/fcastloader.str b/plugins/cinema4d/res/strings_us/description/fcastloader.str index c970d11..0bc109e 100644 --- a/plugins/cinema4d/res/strings_us/description/fcastloader.str +++ b/plugins/cinema4d/res/strings_us/description/fcastloader.str @@ -1,7 +1,7 @@ STRINGTABLE fcastloader { fcastloader "Cast Import"; - CAST_IMPORT_GROUP "Cast Import Settings"; + CAST_IMPORT_GROUP "Settings"; CAST_IMPORT_BIND_SKIN "Import Bind Skin"; CAST_IMPORT_IK_HANDLES "Import IK Handles"; CAST_IMPORT_CONSTRAINTS "Import Constraints";