PyObject *py_ue_skeletal_mesh_set_skeleton(ue_PyUObject * self, PyObject * args) { ue_py_check(self); PyObject *py_skeleton; if (!PyArg_ParseTuple(args, "O:skeletal_mesh_set_skeleton", &py_skeleton)) return nullptr; USkeletalMesh *mesh = ue_py_check_type<USkeletalMesh>(self); if (!mesh) return PyErr_Format(PyExc_Exception, "UObject is not a USkeletalMesh."); USkeleton *skeleton = ue_py_check_type<USkeleton>(py_skeleton); if (!skeleton) return PyErr_Format(PyExc_Exception, "argument is not a USkeleton."); mesh->ReleaseResources(); mesh->ReleaseResourcesFence.Wait(); mesh->Skeleton = skeleton; mesh->RefSkeleton = skeleton->GetReferenceSkeleton(); mesh->RefBasesInvMatrix.Empty(); mesh->CalculateInvRefMatrices(); #if WITH_EDITOR mesh->PostEditChange(); #endif mesh->InitResources(); mesh->MarkPackageDirty(); Py_RETURN_NONE; }
void FLODUtilities::RemoveLOD(FSkeletalMeshUpdateContext& UpdateContext, int32 DesiredLOD ) { USkeletalMesh* SkeletalMesh = UpdateContext.SkeletalMesh; FSkeletalMeshResource* SkelMeshResource = SkeletalMesh->GetImportedResource(); if( SkelMeshResource->LODModels.Num() == 1 ) { FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "NoLODToRemove", "No LODs to remove!") ); return; } // Now display combo to choose which LOD to remove. TArray<FString> LODStrings; LODStrings.AddZeroed( SkelMeshResource->LODModels.Num()-1 ); for(int32 i=0; i<SkelMeshResource->LODModels.Num()-1; i++) { LODStrings[i] = FString::Printf( TEXT("%d"), i+1 ); } check( SkeletalMesh->LODInfo.Num() == SkelMeshResource->LODModels.Num() ); // If its a valid LOD, kill it. if( DesiredLOD > 0 && DesiredLOD < SkelMeshResource->LODModels.Num() ) { //We'll be modifying the skel mesh data so reregister //TODO - do we need to reregister something else instead? FMultiComponentReregisterContext ReregisterContext(UpdateContext.AssociatedComponents); // Release rendering resources before deleting LOD SkelMeshResource->ReleaseResources(); // Block until this is done FlushRenderingCommands(); SkelMeshResource->LODModels.RemoveAt(DesiredLOD); SkeletalMesh->LODInfo.RemoveAt(DesiredLOD); SkeletalMesh->InitResources(); RefreshLODChange(SkeletalMesh); // Set the forced LOD to Auto. for(auto Iter = UpdateContext.AssociatedComponents.CreateIterator(); Iter; ++Iter) { USkinnedMeshComponent* SkinnedComponent = Cast<USkinnedMeshComponent>(*Iter); if(SkinnedComponent) { SkinnedComponent->ForcedLodModel = 0; } } //Notify calling system of change UpdateContext.OnLODChanged.ExecuteIfBound(); // Mark things for saving. SkeletalMesh->MarkPackageDirty(); } }
PyObject *py_ue_skeletal_mesh_set_required_bones(ue_PyUObject *self, PyObject * args) { ue_py_check(self); PyObject *py_map; int lod_index = 0; if (!PyArg_ParseTuple(args, "O|i:skeletal_mesh_set_required_bones", &py_map, &lod_index)) return nullptr; USkeletalMesh *mesh = ue_py_check_type<USkeletalMesh>(self); if (!mesh) return PyErr_Format(PyExc_Exception, "uobject is not a USkeletalMesh"); #if ENGINE_MINOR_VERSION < 19 FSkeletalMeshResource *resource = mesh->GetImportedResource(); #else FSkeletalMeshModel *resource = mesh->GetImportedModel(); #endif if (lod_index < 0 || lod_index >= resource->LODModels.Num()) return PyErr_Format(PyExc_Exception, "invalid LOD index, must be between 0 and %d", resource->LODModels.Num() - 1); #if ENGINE_MINOR_VERSION < 19 FStaticLODModel &model = resource->LODModels[lod_index]; #else FSkeletalMeshLODModel &model = resource->LODModels[lod_index]; #endif PyObject *py_iter = PyObject_GetIter(py_map); if (!py_iter) { return PyErr_Format(PyExc_Exception, "argument is not an iterable of numbers"); } TArray<FBoneIndexType> required_bones; while (PyObject *py_item = PyIter_Next(py_iter)) { if (!PyNumber_Check(py_item)) { Py_DECREF(py_iter); return PyErr_Format(PyExc_Exception, "argument is not an iterable of numbers"); } PyObject *py_num = PyNumber_Long(py_item); uint16 index = PyLong_AsUnsignedLong(py_num); Py_DECREF(py_num); required_bones.Add(index); } Py_DECREF(py_iter); // temporarily disable all USkinnedMeshComponent's TComponentReregisterContext<USkinnedMeshComponent> ReregisterContext; mesh->ReleaseResources(); mesh->ReleaseResourcesFence.Wait(); model.RequiredBones = required_bones; model.RequiredBones.Sort(); mesh->RefBasesInvMatrix.Empty(); mesh->CalculateInvRefMatrices(); #if WITH_EDITOR mesh->PostEditChange(); #endif mesh->InitResources(); mesh->MarkPackageDirty(); Py_RETURN_NONE; }
PyObject *py_ue_skeletal_mesh_set_soft_vertices(ue_PyUObject *self, PyObject * args) { ue_py_check(self); PyObject *py_ss_vertex; int lod_index = 0; int section_index = 0; if (!PyArg_ParseTuple(args, "O|ii:skeletal_mesh_set_soft_vertices", &py_ss_vertex, &lod_index, §ion_index)) return nullptr; USkeletalMesh *mesh = ue_py_check_type<USkeletalMesh>(self); if (!mesh) return PyErr_Format(PyExc_Exception, "uobject is not a USkeletalMesh"); #if ENGINE_MINOR_VERSION < 19 FSkeletalMeshResource *resource = mesh->GetImportedResource(); #else FSkeletalMeshModel *resource = mesh->GetImportedModel(); #endif if (lod_index < 0 || lod_index >= resource->LODModels.Num()) return PyErr_Format(PyExc_Exception, "invalid LOD index, must be between 0 and %d", resource->LODModels.Num() - 1); #if ENGINE_MINOR_VERSION < 19 FStaticLODModel &model = resource->LODModels[lod_index]; #else FSkeletalMeshLODModel &model = resource->LODModels[lod_index]; #endif if (section_index < 0 || section_index >= model.Sections.Num()) return PyErr_Format(PyExc_Exception, "invalid Section index, must be between 0 and %d", model.Sections.Num() - 1); PyObject *py_iter = PyObject_GetIter(py_ss_vertex); if (!py_iter) { return PyErr_Format(PyExc_Exception, "argument is not an iterable of FSoftSkinVertex"); } TArray<FSoftSkinVertex> soft_vertices; while (PyObject *py_item = PyIter_Next(py_iter)) { ue_PyFSoftSkinVertex *ss_vertex = py_ue_is_fsoft_skin_vertex(py_item); if (!ss_vertex) { Py_DECREF(py_iter); return PyErr_Format(PyExc_Exception, "argument is not an iterable of FSoftSkinVertex"); } soft_vertices.Add(ss_vertex->ss_vertex); } Py_DECREF(py_iter); // temporarily disable all USkinnedMeshComponent's TComponentReregisterContext<USkinnedMeshComponent> ReregisterContext; mesh->ReleaseResources(); mesh->ReleaseResourcesFence.Wait(); model.Sections[section_index].SoftVertices = soft_vertices; model.Sections[section_index].NumVertices = soft_vertices.Num(); model.Sections[section_index].CalcMaxBoneInfluences(); mesh->RefBasesInvMatrix.Empty(); mesh->CalculateInvRefMatrices(); #if WITH_EDITOR mesh->PostEditChange(); #endif mesh->InitResources(); mesh->MarkPackageDirty(); Py_RETURN_NONE; }