Sort metal tube

en français ce sera plus clair…
ta solution revient à dire, j’arrête la boucle si len(liste2) est égal ou supérieur à len(liste1) ET le compteur a depassé 200…
moi je voulais que la boucle s’arrête si la longueur dépasse celle de l’autre ou que le compteur dépasse les 200 au cas ou ma liste n’atteindrait pas la longueur de la première…

pour le deuxième point:
je ne vois pas où je nomme tout les tubes d’un coup,
je nome le premier tube que je passe dans la liste 2
je recupère toute les données à comparer,
je lance une deuxième boucle qui va passer tout les tubes de la première liste,
si toutes les comparaisons sont True, alors je nomme le tube, et je le deplace dans la deuxième liste,
une fois que ça c’est fait je prend le deuxième tube de la liste,
si il a un nom, c’est que c’est déjà le doublon d’un autre, et il est déjà dans la liste 2, alors je passe au suivant, si il n’a pas nom je récupère c’est données…

mais il est vrai que ça marche pas et je ne vois pas où…???

2ème ligne ici:

            if rs.ObjectName(Tube)==None:
                rs.ObjectName(Tube,NewName)
                ...
                if ... if ... if ...if ...
                                        rs.ObjectName(Tubes[i],NewName)

Something like this…?
onlyfortubes.py (4.4 KB)

1 Like

And here with the Counter:

onlyfortubes.py (4.9 KB)

how can i say…???
that it’s!!! thank you…
i would like to find it by myself… but i don’t know why…

You’re welcome :slight_smile: you got most of the way there, keep up the good work!!!

Sorry, but there is a problem and since yesterday i didn’t find where is the problem… some Tubes don’t have name… i don’t know why?
i think that when we remove a tube of Tubes, all tubes of the end, take the place before, and at the next loop, it pass a tube? is it possible?

in the script the only chance to remove the tube that is the condition is ObjectName==None,
but at the end of the script, it rest some tube, that’s means, they had got a name…

        rs.SelectObject(Tube)
        NewName=PrefixTube+str(n)
        print rs.ObjectName(Tube)
        if rs.ObjectName(Tube)==None:
            rs.ObjectName(Tube,NewName)
            print rs.ObjectName(Tube)
            Chk_Lg=rs.GetUserText(Tube,'Lg')
            Chk_Sect=rs.GetUserText(Tube,'Section')
            Chk_A1=rs.GetUserText(Tube,'Angle1')
            Chk_A2=rs.GetUserText(Tube,'Angle2')
            TubesNom.append(Tube)
            Tubes.remove(Tube)

YES!!!
thank you for your time, my script is ok now…
i found all i need…
i have to search for write on a layout but for the moment it’s ok!

for analyse tubes and named:

# coding: utf-8
import rhinoscriptsyntax as rs

def TriTube(Tubes):
    Tubes.sort(key = lambda Tube : rs.SurfaceVolume(Tube)[0])
    Tubes.reverse()
    return Tubes

def TriSurf (Surfs):
    Surfs=sorted([(rs.SurfaceArea(Surf)[0],Surf) for Surf in Surfs])
    return [item[1] for item in Surfs]

def TriEdge (ArrEdge):
    ArrEdge=sorted([(rs.CurveLength(Edge),Edge) for Edge in ArrEdge])
    return [item[1] for item in ArrEdge]
    
def VectNormSurf(Surf):
    UDom=rs.SurfaceDomain(Surf,0)
    VDom=rs.SurfaceDomain(Surf,1)
    NormSurf=rs.SurfaceNormal(Surf,((UDom[1]-UDom[0])/2,(VDom[1]-VDom[0])/2))
    return NormSurf



def MUserTex(Tube):
    Surfs=rs.ExplodePolysurfaces(Tube)
    Surfs=TriSurf(Surfs)
    ArrEdge=rs.DuplicateEdgeCurves(Surfs[len(Surfs)-1], select=False)
    ArrEdge=TriEdge(ArrEdge)
    NormSurf=VectNormSurf(Surfs[len(Surfs)-1])
    Origine=rs.CurveStartPoint(ArrEdge[len(ArrEdge)-1])
    XVect=rs.CurveEndPoint(ArrEdge[len(ArrEdge)-1])-rs.CurveStartPoint(ArrEdge[len(ArrEdge)-1])
    Plane=rs.PlaneFromNormal(Origine,NormSurf,XVect)
    #rs.AddPlaneSurface(Plane, 500,500)

    BBox=rs.BoundingBox(Tube,Plane)
    Lg=rs.Distance(BBox[0],BBox[1])
    AngleE=[0,0]
    #definition coupe ou pas
    VolBox=rs.Distance(BBox[0],BBox[1])*rs.Distance(BBox[0],BBox[3])*rs.Distance(BBox[0],BBox[4])
    VolTube=rs.SurfaceVolume(Tube)
    if round(VolBox,2)<>round(VolTube[0],2):
        SurfAppui=None
        #vecteur Petite surface
        for aa in range (0,2):
            NormSurfE=VectNormSurf(Surfs[aa])
            #vecteur grande surface
            if SurfAppui!=None:
                NormSurf=VectNormSurf(SurfAppui)
                AngleETemp=rs.VectorAngle(NormSurf,NormSurfE)
                AngleE[aa]=-(AngleETemp-90)
            else:
                for bb in range(2,6):
                    NormSurf=VectNormSurf(Surfs[bb])
                    AngleETemp=rs.VectorAngle(NormSurf,NormSurfE)
                    if int(round(AngleETemp))!=90:
                        SurfAppui=Surfs[bb]
                        AngleE[aa]=-(AngleETemp-90)
                        break

    rs.DeleteObjects(ArrEdge)
    rs.DeleteObjects(Surfs)

    Lgretenu=int(round(Lg))
    htTube=int(round(rs.Distance(BBox[3],BBox[0])))
    largTube=int(round(rs.Distance(BBox[4],BBox[0])))
    Sectionretenu=str(htTube)+'x'+str(largTube)
    Angle1=int(round(AngleE[0]))
    Angle2=int(round(AngleE[1]))
    print 'longueur', Lgretenu
    print 'Section', htTube,'x',largTube
    print 'angle 1=',Angle1,'°'
    print 'angle 2=',Angle2,'°'
    rs.SetUserText(Tube,'Lg',str(Lgretenu))
    rs.SetUserText(Tube,'Section',Sectionretenu)
    rs.SetUserText(Tube,'Angle1',str(Angle1))
    rs.SetUserText(Tube,'Angle2',str(Angle2))


def main():    
    Tubes=rs.GetObjects("selectionne l'ensemble des tubes",rs.filter.polysurface)
    Tubes2=[]
    chk_red=False
    chk=False
    for Tube in Tubes:
        if rs.IsPolysurfaceClosed(Tube):
            Tubes2.append(Tube)
        else:
            chk_red=True
            rs.ObjectColor( Tube, (250,0,0))
        Tubes=Tubes2
    if chk_red:
        Cont_script=rs.MessageBox('les Tubes rouges ne sont pas fermées, on continue?',4,title='ATTENTION')
        if Cont_script==7:
            return
    for Tube in Tubes:
        chk_name=rs.ObjectName(Tube)
        if chk_name!=None and chk==False:
            Cont_script=rs.MessageBox('au moins un tube à déjà un nom, on renomme et on continue?',4,title='ATTENTION')
            chk=True
            if Cont_script==7:
                return
        rs.ObjectName(Tube,'')
    if Tubes:
        PrefixTube=rs.GetString("une lettre de nommage?")
    if PrefixTube:
        Tubes=TriTube(Tubes)
        for Tube in Tubes:
            MUserTex(Tube)
    TubesNom=[]
    n=1
    for Tube in Tubes:
#        rs.SelectObject(Tube)

        NewName=PrefixTube+'.'+str(n)
        print rs.ObjectName(Tube)
        if rs.ObjectName(Tube)==None:
            rs.ObjectName(Tube,NewName)
            print rs.ObjectName(Tube)
            Chk_Lg=rs.GetUserText(Tube,'Lg')
            Chk_Sect=rs.GetUserText(Tube,'Section')
            Chk_A1=rs.GetUserText(Tube,'Angle1')
            Chk_A2=rs.GetUserText(Tube,'Angle2')
            TubesNom.append(Tube)
            #Tubes.remove(Tube)
            items=Tubes
            for item in items:
#                rs.SelectObject(item)
                if rs.ObjectName(item)==None:
                    if rs.GetUserText(item,'Lg')==Chk_Lg:
                        if rs.GetUserText(item,'Section')==Chk_Sect:
                            if rs.GetUserText(item,'Angle1')==Chk_A1:
                                if rs.GetUserText(item,'Angle2')==Chk_A2:
                                    rs.ObjectName(item,NewName)
                                    TubesNom.append(item)
#                rs.UnselectObject(item)
            n+=1
#        rs.UnselectAllObjects()
    rs.SelectObjects(TubesNom)

    
if __name__ =="__main__":
    main()

and for write the BOM:

# coding: utf-8
import rhinoscriptsyntax as rs
from collections import Counter

def ExtractName(str):
    if '.' in str:
        pos=str.index('.')
        temp=str.split('.')
        return temp[0]
    else:
        return str[0]

def main():    
    Tubes=rs.GetObjects("selectionne l'ensemble des tubes",rs.filter.polysurface)

    TubeCounter = Counter()
    lstcount=[]
    lstname=[]
    lstlen=[]
    #recupère le nom, les quantité,les longueurs à mettre dans une liste
    for tube in Tubes:
        Name=rs.ObjectName(tube)
        Lg = rs.GetUserText(tube, 'Lg')
        data = (Lg,Name)
        TubeCounter.update([data])
    for item, count in TubeCounter.iteritems():
        lstcount.append(count)
        lstname.append(item[1])
        lstlen.append(int(item[0]))
    print lstcount
    print lstname
    print lstlen
    #tri les listes par longueurs
    lsttotal=[]
    for i in range (0,len(lstcount)):
        lsttotal.append((lstcount[i],lstname[i],lstlen[i]))
    lst_sort=sorted(lsttotal,key=lambda s:s[2],reverse=True)
    sorted_lstlen=[]
    sorted_lstname=[]
    sorted_lstcount=[]
    for item in lst_sort:
        sorted_lstlen.append(item[2])
        sorted_lstname.append(item[1]) 
        sorted_lstcount.append(item[0]) 

    text=''
    # récupères toutes les données par tubes et les ajoute en chaine de textes
    for i in range(0,len(sorted_lstlen)):
        select_by_name=rs.ObjectsByName(sorted_lstname[i])
        rs.SelectObject(select_by_name[0])
        Name=rs.ObjectName(select_by_name[0])
        Lg = rs.GetUserText(select_by_name[0], 'Lg')
        Section = rs.GetUserText(select_by_name[0], 'Section')
        Angle1 = rs.GetUserText(select_by_name[0], 'Angle1')
        Angle2 = rs.GetUserText(select_by_name[0], 'Angle2')
        text=text+Name+'  :  '+str(lstcount[i])+' x '+' Lg='+Lg+'mm   Angle= '+Angle1+'°/'+Angle2+'°\n'
        rs.UnselectAllObjects()
    
    print text
    #Ajout un Calque
    LayerName=ExtractName(Name)
    text='STRUCTURE '+LayerName+'   ' + Section +'\n' + text
    rs.AddLayer('NOMENCLATURE')
    rs.AddLayer(LayerName,(0,0,0),parent='NOMENCLATURE')
    rs.CurrentLayer(LayerName)
    rs.AddText(text,(0,0,0),5)

if __name__ =="__main__":
    main()