บางครั้งเราอาจต้องการสร้างวัตถุที่มีลักษณะเหมือนเดิมซ้ำๆหรือคล้ายจากเดิมหลายอัน
  โดยปกติเราสามารถใช้การวนซ้ำ for หรือ while เพื่อสร้างวัตถุที่ต้องการขึ้นมากี่อันก็ได้ตามที่ต้องการอยู่แล้ว 
 แต่ว่าบางครั้งการซ้ำกระบวนการสร้างเดิมอยู่หลายๆครั้งนั้นเป็นอะไรที่ต้องใช้ เวลา ยิ่งวัตถุมีรูปร่างซับซ้อน กว่าจะทำออกมาได้อันหนึ่งก็ยิ่งนาน 
 กรณีที่มีวัตถุที่ต้องการวัตถุที่ซ้ำๆกันหรือสามารถแปลงรูปจากรูปร่างที่มีอยู่ ได้โดยง่าย เราสามารถใช้วิธีการทำสำเนาของวัตถุได้ โดยฟังก์ชันที่ใช้ก็คือ duplicate() 
 การใช้งานนั้นง่ายมาก แค่กดเลือกที่วัตถุที่ต้องการทำการสำเนาแล้วก็พิมพ์ mc.duplicate() เท่านี้ก็ได้วัตถุชิ้นเดิมอีกอันซึ่งอยู่ในตำแหน่งเดียวกัน จากนั้นก็กดย้ายมันไปไว้ในตำแหน่งอื่นตามที่ต้องการ เช่น
mc.polySphere(r=1)
 for i in range(10):
     mc.duplicate()
     mc.move(i*2,i*2,0)
  
  (หมายเหตุ ภาพในบทนี้มีการปรับแสงไฟโดยใช้ไฟสามสีจาก
บทที่แล้ว หากไม่มีแสงวัตถุจะเป็นสีเทาตามปกติ) 
 หรือถ้าใส่ชื่อของวัตถุที่ต้องการทำสำเนาลงไปเป็นอาร์กิวเมนต์ก็สามารถสำเนาวัตถุได้แม้จะไม่ได้เลือกอยู่ 
 วัตถุที่ถูกทำสำเนาขึ้นมาใหม่สามารถตั้งชื่อได้เช่นกันโดยใส่แฟล้ก n (name) ถ้าไม่ตั้งจะถูกตั้งให้โดยอัตโนมัติให้สัมพันธ์กับวัตถุต้นฉบับ   
 เพื่อแสดงให้เห็นว่าการสำเนาวัตถุขึ้นมาใหม่นั้นเร็วกว่าการสร้างขึ้นมาใหม่ เราจะลองทดสอบความต่างของเวลาที่ใช้ดูได้ด้วยฟังก์ชัน time ซึ่งอยู่คำสั่ง time ซึ่งเป็นชุดคำสั่งมาตรฐานของไพธอนที่มีอยู่แล้ว 
 วิธีใช้
import time # ประกาศนำเข้าชุดคำสั่ง
 t0 = time.time() # เวลาเริ่มต้น
 <กลุ่มคำสั่งที่ต้องการจับเวลา>
 print(time.time() - t0) # พิมพ์เวลาสุดท้ายลบด้วยเวลาเริ่มต้น
 เราลองทดสอบโดยการใช้จับเวลาเปรียบเทียบระหว่างใช้การสำเนากับใช้การวนซ้ำเพื่อสร้างใหม่ 
 ลองสร้างวัตถุทรงกลมที่รวมกันเป็นกลุ่ม ๓๘ ลูก โดยเริ่มแรกจับเวลาที่ใช้สร้างด้วยวิธีสร้างซ้ำแล้วก็พิมพ์เวลาออกมา จากนั้นก็สร้างเหมือนเดิมอีกด้วยวิธีการทำสำเนา แล้วก็พิมพ์เวลาออกมาอีก จากนั้นลองเทียบกันดู
import time
 k = [1,4,8,12,8,4,1]
 # ใช้วิธีสร้างซ้ำ
 t0 = time.time()
 g = [] # สร้างลิสต์ที่เก็บชื่อของวัตถุ
 for j in range(7):
     for i in range(k[j]):
         g += mc.polySphere(r=1,ch=0) # สร้างทรงกลมใหม่ พร้อมเพิ่มชื่อเข้าลิสต์
         mc.move(0,2,0) # ย้ายไปไว้ตำแหน่งขั้วเหนือ
         mc.rotate(j*30,360/k[j]*i,0,p=[0,0,0]) # หมุนตามแนวละติจูดและลองจิจูด
 mc.group(g) # รวมกลุ่ม
 print(time.time() - t0) # พิมพ์เวลาที่ใช้
 # ใช้วิธีทำสำเนาไปเรื่อยๆ
 t0 = time.time()    
 g = mc.polySphere(r=1,ch=0) # สร้างทรงกลมลูกแรก พร้อมเก็บชื่อลิสต์
 mc.move(0,2,0)
 for j in range(1,7):
     for i in range(k[j]):
         g += mc.duplicate() # ทำสำเนา พร้อมเพิ่มชื่อเข้าลิสต์
         mc.rotate(j*30,360/k[j]*i,0,p=[0,0,0])
 mc.group(g) # รวมกลุ่ม
 print(time.time() - t0) # พิมพ์เวลาที่ใช้
  
  จะได้ตัวเลขเวลาออกมาสองค่า จะเห็นว่าเลขตัวแรกจะมากกว่า นั่นคือวิธีการทำสำเนานั้นใช้เวลาน้อยกว่า ดังนั้นจึงช่วยประหยัดเวลาในการสร้างได้ แม้ว่าผลลัพธ์สุดท้ายจะเหมือนกันก็ตาม   
 การสำเนานั้นไม่เพียงทำกับตัววัตถุทีละชิ้นเท่านั้น ยังสามารถสำเนาวัตถุพรุ้อมกันหลายชิ้น หรืออาจสำเนากลุ่มของวัตถุก็ได้ 
 ปกติเวลาที่ใช้ duplicate() ฟังก์ชันจะคืนค่าลิสต์ของวัตถุที่ถูกสำเนากลับคืนมาทั้งหมด กรณีที่สำเนากลุ่ม จะได้ทั้งชื่อของกลุ่มและชื่อของวัตถุในกลุ่มมาพร้อมกัน 
 ลองเทียบอีกตัวอย่างหนึ่งที่ซับซ้อนกว่าเดิม คราวนี้ลองเอากลุ่มทรงกลมที่ได้ออกมานั้นมานั้นมาสร้างใหม่ซ้ำๆแล้วรวมเป็นก ลุ่มที่ใหญ่ขึ้นไปอีก
import time
 k = [1,4,8,12,8,4,1]
 # ใช้วิธีสร้างซ้ำ
 t1 = time.time()
 gg = [] # สร้างลิสต์ที่เก็บชื่อของกลุ่มทรงกลม
 for n in range(7): # วงใหญ่ (วนซ้ำเพื่อสร้างกลุ่มของทรงกลมที่ถูกสร้างในวงย่อย)
     for m in range(k[n]):
         g = [] # สร้างลิสต์ที่เก็บชื่อของทรงกลมย่อย
         for j in range(7): # วงย่อย (สร้างทรงกลมย่อย)
             for i in range(k[j]):
                 g += mc.polySphere(r=1,ch=0) # สร้างทรงกลมย่อยพร้อมเก็บชื่อเข้าลิสต์
                 mc.move(0,2,0)
                 mc.rotate(j*30,360/k[j]*i,0,p=[0,0,0])
         gg += [mc.group(g)] # รวมทรงกลมย่อยเป็นกลุ่มพร้อมเพิ่มชื่อเข้าลิสต์
         mc.move(0,6,0)
         mc.rotate(n*30,360/k[n]*m,0,p=[0,0,0])
 mc.group(gg) # รวมกลุ่มทรงกลมเป็นใหญ่
 print(time.time() - t1) # พิมพ์เวลาที่ใช้
 # ใช้วิธีทำสำเนาไปเรื่อยๆ
 t1 = time.time()
 g = mc.polySphere(r=1,ch=0) # สร้างทรงกลมย่อยลูกแรก
 mc.move(0,2,0)
 for j in range(1,7): 
     for i in range(k[j]):
         g += mc.duplicate() # สำเนาทรงกลมย่อย
         mc.rotate(j*30,360/k[j]*i,0,p=[0,0,0])
 gg = [mc.group(g)] # รวมกลุ่มเป็นกลุ่มทรงกลมกลุ่มแรก พร้อมเก็บชื่อเข้าลิสต์ที่เก็บชื่อกลุ่มทรงกลม
 mc.move(0,6,0)
 for j in range(1,7):
     for i in range(k[j]):
         gg += [mc.duplicate()[0]] # สำเนากลุ่มทรงกลม พร้อมเก็บชื่อเข้าลิสต์ โดย [0] ในที่นี้หมายถึงเอาเฉพาะชื่อของกลุ่มซึ่งเป็นชื่อแรกที่ฟังก์ชันคืนกลับมา
         mc.rotate(j*30,360/k[j]*i,0,p=[0,0,0])
 mc.group(gg) # รวมกลุ่มทรงกลมเป็นกลุ่มใหญ่
 print(time.time() - t1) # พิมพ์เวลาที่ใช้
 จะเห็นว่าใช้การทำสำเนานั้นให้ผลเป็นเวลาที่เร็วกว่า อีกทั้งโค้ดดูง่ายกว่า ไม่ต้องสร้างวงวนซ้ำซ้อนกัน  
 
    อนึ่ง หากลองไปดูที่ชื่อของกลุ่มที่ถูกสำเนาขึ้นมาจะเห็นว่าชื่อเหมือนกันหมดทุก กลุ่ม เช่นในกลุ่ม group40 ถึง group 77 จะมีวัตถุชื่อ pSphere1445 ถึง  pSphere1482 อยู่เหมือนกันหมด 
 หากมีวัตถุชื่อซ้ำกันจะมีปัญหาเวลาที่ อ้างอิงถึงวัตถุนั้น ถ้าหากพิมพ์แค่ชื่อวัตถุนั้นลงไปเช่น mc.select('pSphere1445') ก็จะพบว่าโปรแกรมขัดข้องเพราะไม่รู้ว่าหมายถึงชิ้นไหน 
 แต่สำหรับวัตถุที่แม้จะชื่อซ้ำกันแต่อยู่สังกัดคนละกลุ่มกันก็สามารถแยกแยะได้โดย พิมพ์ชื่อกลุ่มที่สังกัดนำหน้าไว้แล้วตามด้วย | แล้วค่อยตามด้วยชื่อวัตถุนั้น เช่นในกรณีนี้พิมพ์เป็น
mc.select('group40|pSphere1445')
 ก็จะเป็นการเลือกวัตถุ pSphere1445 ที่อยู่ในกลุ่ม group40 ไม่ใช่ที่อยู่ในกลุ่มอื่น สามารถแยกแยะกันได้ชัดเจนไม่มีปัญหาอะไร  
 
  ดังนั้นโดยทั่วไปอาจไม่ต้องคิดมากเรื่องที่ชื่อซ้ำ ถือเป็นเรื่องปกติและยังทำให้สะดวกในการอ้างอิงด้วย 
 อย่างไรก็ตามตอนที่สำเนาหากต้องการเปลี่ยนชื่อวัตถุที่อยู่ในกลุ่มให้ไม่ซ้ำกันก็ สามารถทำได้โดยเพิ่มแฟล็ก rc (renameChildren) เป็น rc=1 แล้วชื่อวัตถุก็จะถูกเปลี่ยนให้ไม่ซ้ำกัน 
 ลองสร้างใหม่โดยใช้โค้ด ตัวอย่างที่แล้ว โดยแค่เพิ่มแฟล็ก rc=1 ลงในฟังก์ชัน duplicate() เป็น mc.duplicate(rc=1) ทั้งสองที่ จะได้ผลเหมือนเดิมแต่ต่างกันแค่ชื่อของวัตถุ  
 
    นอกจากนี้การสำเนาไม่ได้ทำได้เพียงแค่วัตถุที่จับต้องได้เท่านั้น ยังสามารถใช้กับโหนดอย่างอื่นด้วย เช่นเท็กซ์เจอร์หรือวัสดุ ฯลฯ ได้ด้วยเช่นกัน 
 duplicate() เป็นคำสั่งที่มีประโยชน์มากมาย น่าจะได้ใช้กันต่อไปอีกเยอะ    
อ้างอิง