How to reduce the number of curves by percentage?

How to reduce the number of curves by percentage?

niuxihuanming
Participant Participant
449 Views
4 Replies
Message 1 of 5

How to reduce the number of curves by percentage?

niuxihuanming
Participant
Participant

Hello everyone, I am working on a plug-in with a percentage decreasing curve, but it does not seem to be in the order of 1-100, is there a problem?228a001fd78381b986616a36232595b.png

import random
import maya.cmds as cmds
import maya.mel as mel

def run():
    percentage = cmds.intSliderGrp("intsample", q=True, value=True)               
    
    objs = cmds.ls(sl=True)
    if len(objs) == 1:
        all_childs = cmds.listRelatives(objs[0])
    else:
        all_childs = objs
    indeces = []
    i = 0
    while i < int(len(all_childs) * percentage):
        index = int(round(random.uniform(0, len(all_childs) - 1)))
        if index not in indeces:
            indeces.append(index)
        else:
            i -= 1
        i += 1

        for each in indeces:
            cmds.delete(all_childs[each])

        objs = cmds.ls(sl=True)
        if len(objs) == 1:
            all_childs = cmds.listRelatives(objs[0])
        else:
            all_childs = objs
        print ('Remains:', len(all_childs))
    else:
        mel.eval('print("Please Enter A number for Percentage!")')
                
cmds.window( title='Del_curve')
cmds.columnLayout()
           
cmds.intSliderGrp("intsample", h=30, f=1, l='%:', min=1, max=100, value=1, cw=(50, 120), dc="run()")
cmds.showWindow()

 

0 Likes
Accepted solutions (1)
450 Views
4 Replies
Replies (4)
Message 2 of 5

jmreinhart
Advisor
Advisor

Hi, so this code should do what you want. 

In the future, when you post a question it is helpful if you say "I want my code to do this, but right now it does this". If you are more specific it will be easier for people to help 🙂

import random
import maya.cmds as cmds
import maya.mel as mel

class percentWindow():
    delete_indices = []
    all_childs = []
    
    def __init__(self):
        self.getChildren()
        self.createWindow()
        
    def createWindow(self):
        cmds.window( title='Del_curve')
        cmds.columnLayout()
                   
        cmds.intSliderGrp("intsample", h=30, f=1, l='%:', min=1, max=100, value=1, cw=(50, 120), dc=self.run)
        cmds.button("Delete", command = self.deleteCmd)
        cmds.showWindow()
        
    def getChildren(self):
        # Get the selected objects
        objs = cmds.ls(sl=True)
        # Get the children of those objects
        if len(objs) == 1:
            self.all_childs = cmds.listRelatives(objs[0])
        else:
            self.all_childs = objs
    
    def run(self, slider_val):
        # Get the perecentage from the slider
        percentage = float(slider_val)/100.0               
        
        # Calculate the number of objects we will delete
        num_to_delete = int(len(self.all_childs) * percentage)
        
        # Get num_to_delete unique integers
        self.delete_indices = random.sample(range(0,  len(self.all_childs) - 1), num_to_delete)

        # Select those items
        cmds.select(cl = True)
        for index in self.delete_indices:
            cmds.select(self.all_childs[index], add = True)
        
    def deleteCmd(self, btn_val):
        for index in self.delete_indices:
            cmds.delete(self.all_childs[index])
            
percentWindow()
Message 3 of 5

Kahylan
Advisor
Advisor
Accepted solution

Hi!

 

The problem is, that you are reading out the percentage as a whole number but you are using the percentage formula for decimal percentages. (i.e whole number percentage:10%, decimal percentage: 0.1)

 

To get to your correct value you would need to use ((len(all_childs)/100)*percentage)

 

But I have to say, that the way you are doing this, with the while loop and an additional if else statement inside seems rather complex for completing such an easy task.

I would write your function probably like this:

 

import maya.cmds as cmds
import random

def run():
    
    percentage = cmds.intSliderGrp("intsample", q=True, value=True) 
    objs = cmds.ls(sl =True)
    
    if len(objs) == 1:
        all_children = cmds.listRelatives(objs[0])
    else:
        all_children = objs
    
    num = round((len(all_children)/100)*percentage)
    
    for n in range(0,num):
        keep = random.choice(all_children)
        all_children.remove(keep)
    
    cmds.delete(all_children)

cmds.window( title='Del_curve')
cmds.columnLayout()
           
cmds.intSliderGrp("intsample", h=30, f=1, l='%:', min=1, max=100, value=1, cw=(50, 120))
btn = cmds.button("run", l = "reduce", c = "run()")
cmds.showWindow()
    

 

 

I also added a button to the UI that executes the function. Having something that deletes objects on a drop change command will cause user frustration.

 

I hope it helps!

 

EDIT: Oh sry @jmreinhart, I didn't see that you already had answered this until I had posted my reply.

Message 4 of 5

niuxihuanming
Participant
Participant

Thank you, I took another approach.

Message 5 of 5

niuxihuanming
Participant
Participant
Thank you, this method of yours is effective.
0 Likes