यह एक स्क्रिप्ट के लिए है जिसे मैं ब्लेंडर में चला रहा हूं, लेकिन सवाल इसके पायथन हिस्से से संबंधित है। यह ब्लेंडर के लिए विशिष्ट नहीं है।
स्क्रिप्ट मूल रूप से इस उत्तर की है, और यह किसी दी गई सामग्री (कुंजी) को उसके नए समकक्ष ( मूल्य)।
यहाँ कोड है:
import bpy
objects = bpy.context.selected_objects
mat_dict = {
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
}
for obj in objects:
for slot in obj.material_slots:
slot.material = bpy.data.materials[mat_dict[slot.material.name]]
रोड़ा है, डुप्लिकेट को कैसे संभालना है जब दृश्य में "सॉलिड-व्हाइट" सामग्री के साथ न केवल ऑब्जेक्ट हो सकते हैं, बल्कि "सॉलिड-व्हाइट.001", "सॉलिड-व्हाइट.002", और इसी तरह।
मैं पाइथन में वाइल्डकार्ड के बारे में एक प्रश्न के लिए this answer देख रहा था और ऐसा लगता है कि fnmatch
अच्छी तरह से अनुकूल हो सकता है इस कार्य के लिए।
मैंने कोड की अंतिम पंक्ति में fnmatch
काम करने की कोशिश की है। मैंने इसके साथ शब्दकोश कुंजियों को लपेटने का भी प्रयास किया है (बहुत गीला, मुझे पता है)। इनमें से किसी भी दृष्टिकोण ने काम नहीं किया है।
मैं प्रत्येक शब्दकोश कुंजी पर वाइल्डकार्ड मिलान कैसे चला सकता हूं?
तो उदाहरण के लिए, क्या किसी ऑब्जेक्ट में "सॉलिड-व्हाइट" या "सॉलिड-व्हाइट" -डॉट-कुछ-नंबर है, फिर भी इसे "Sld_WHITE" से बदल दिया जाएगा?
2 जवाब
मुझे ब्लेंडर के बारे में कोई जानकारी नहीं है इसलिए मुझे यकीन नहीं है कि मुझे समस्या ठीक हो रही है, लेकिन निम्नलिखित के बारे में कैसे?
mat_dict = {
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
}
def get_new_material(old_material):
for k, v in mat_dict.items():
# .split(".")[0] extracts the part to the left of the dot (if there is one)
if old_material.split(".")[0] == k:
return v
return old_material
for obj in objects:
for slot in obj.material_slots:
new_material = get_new_material(slot.material.name)
slot.material = bpy.data.materials[new_material]
.split(".")[0]
के बजाय आप या re.match
रेगेक्स को अपने शब्दकोश में कुंजियों के रूप में संग्रहीत करके उपयोग कर सकते हैं। जैसा कि आपने टिप्पणी में देखा, startswith
बहुत अधिक मेल खा सकता है, और fnmatch
के मामले में भी ऐसा ही होगा।
कार्रवाई में उपरोक्त फ़ंक्शन के उदाहरण:
In [3]: get_new_material("SOLID-WHITE.001")
Out[3]: 'Sld_WHITE'
In [4]: get_new_material("SOLID-WHITE")
Out[4]: 'Sld_WHITE'
In [5]: get_new_material("SOLID-BLACK")
Out[5]: 'Sld_BLACK'
In [6]: get_new_material("test")
Out[6]: 'test'
आप दो तरीकों से इस तक पहुंच सकते हैं। आप एक ऐसा स्मार्ट डिक्शनरी बना सकते हैं जो अस्पष्ट नामों से मेल खाता हो। या आप उस कुंजी को बदल सकते हैं जिसका उपयोग रंग देखने के लिए किया जाता है।
यहाँ fnmatch का उपयोग करने वाले पहले दृष्टिकोण का एक उदाहरण दिया गया है। यह दृष्टिकोण लुकअप समय की जटिलता को O(1) से O(n) में बदल देता है जब रंग में कोई संख्या होती है। यह दृष्टिकोण __missing__
विधि के साथ UserDict का विस्तार करता है . शब्दकोश में कुंजी नहीं मिलने पर __missing__
विधि को कॉल किया जाता है। यह fnmatch का उपयोग करके दी गई कुंजी के साथ प्रत्येक कुंजी की तुलना करता है।
from collections import UserDict
import fnmatch
import bpy
objects = bpy.context.selected_objects
class Colors(UserDict):
def __missing__(self, key):
for color in self.keys():
if fnmatch.fnmatch(key, color + "*"):
return self[color]
raise KeyError(f"could not match {key}")
mat_dict = Colors({
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
})
for obj in objects:
for slot in obj.material_slots:
slot.material = bpy.data.materials[mat_dict[slot.material.name]]
रेगेक्स का उपयोग करके दूसरे दृष्टिकोण का एक उदाहरण यहां दिया गया है।
import re
import bpy
objects = bpy.context.selected_objects
mat_dict = {
"SOLID-WHITE": "Sld_WHITE",
"SOLID-BLACK": "Sld_BLACK",
"SOLID-BLUE": "Sld_BLUE"
}
pattern = re.compile(r"([A-Z\-]+)(?:\.\d+)?")
# matches any number of capital letters and dashes
# can be followed by a dot followed by any number of digits
# this pattern can match the following strings
# ["AAAAA", "----", "AA-AA.00005"]
for obj in objects:
for slot in obj.material_slots:
match = pattern.fullmatch(slot.material.name)
if match:
slot.material = bpy.data.materials[mat_dict[match.group(1)]]
else:
slot.material = bpy.data.materials[mat_dict[slot.material.name]]
संबंधित सवाल
जुड़े हुए प्रश्न
नए सवाल
python
पायथन एक बहु-प्रतिमान है, गतिशील रूप से टाइप किया हुआ, बहुउद्देशीय प्रोग्रामिंग भाषा है। यह एक साफ और एक समान वाक्यविन्यास सीखने, समझने और उपयोग करने के लिए त्वरित होने के लिए डिज़ाइन किया गया है। कृपया ध्यान दें कि अजगर 2 आधिकारिक तौर पर 01-01-2020 के समर्थन से बाहर है। फिर भी, संस्करण-विशिष्ट पायथन सवालों के लिए, [अजगर -२.०] या [अजगर -३.x] टैग जोड़ें। पायथन वेरिएंट (जैसे, ज्योथन, PyPy) या लाइब्रेरी (उदा।, पांडस और न्यूमपी) का उपयोग करते समय, कृपया इसे टैग में शामिल करें।