Can anyone help me to get this pythonscript work for lists instead of instance ?
Thank you.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
surf = IN[0] #surface to divide in rectangles
polyg = IN[1] #polygon created from the surface
Xs = IN[2] #Unique and sorted X coordinates
Ys = IN[3] #Unique and sorted Y coordinates
Zs = IN[4] #Unique and sorted Zs coordinates
class Rect :
#Class : rectangles that compose the surface
def __init__(self, u_min, u_max, v_min, v_max, w, direction):
#Constructor : u_min,u_max,v_min and v_max are the extreme coordinates on both directions, w is the coordinate in the third direction (all extreme points share this coordinate), direction is the plane that contains the Rect
self.direction = direction; #defines the direction of the Rect
self.w = w; #defines the third coordinate of the Rect
self.u_min = u_min;
self.u_max = u_max;
self.v_min = v_min;
self.v_max = v_max;
#Definition of the 4 points that define the Rect, plus the center of the Rect (pt0)
if(direction=="X"):
self.pt1 = Point.ByCoordinates(w,u_min,v_min);
self.pt2 = Point.ByCoordinates(w,u_min,v_max);
self.pt3 = Point.ByCoordinates(w,u_max,v_max);
self.pt4 = Point.ByCoordinates(w,u_max,v_min);
self.pt0 = Point.ByCoordinates(w,0.5*u_min+0.5*u_max,0.5*v_min+0.5*v_max);
elif(direction == "Y"):
self.pt1 = Point.ByCoordinates(u_min,w,v_min);
self.pt2 = Point.ByCoordinates(u_min,w,v_max);
self.pt3 = Point.ByCoordinates(u_max,w,v_max);
self.pt4 = Point.ByCoordinates(u_max,w,v_min);
self.pt0 = Point.ByCoordinates(0.5*u_min+0.5*u_max,w,0.5*v_min+0.5*v_max);
else:
self.pt1 = Point.ByCoordinates(u_min,v_min,w);
self.pt2 = Point.ByCoordinates(u_min,v_max,w);
self.pt3 = Point.ByCoordinates(u_max,v_max,w);
self.pt4 = Point.ByCoordinates(u_max,v_min,w);
self.pt0 = Point.ByCoordinates(0.5*u_min+0.5*u_max,0.5*v_min+0.5*v_max,w);
def contenu(self, polyg):
#Determines if the Rect is contained by a polygon
return Polygon.ContainmentTest(polyg,self.pt0)
def fusionnable(self,autre_rect):
#Determines if two Rect can be merged, i.e. if they share exactly a side
bool1 = (self.u_max == autre_rect.u_min or self.u_min == autre_rect.u_max) and (self.v_min == autre_rect.v_min and self.v_max == autre_rect.v_max)
bool2 = (self.v_max == autre_rect.v_min or self.v_min == autre_rect.v_max) and (self.u_min == autre_rect.u_min and self.u_max == autre_rect.u_max)
return (bool1 or bool2);
def fusion(self, autre_rect):
#Returns a new Rect that is the fusion of two mergeable Rect
u_m = min(self.u_min,autre_rect.u_min);
u_M = max(self.u_max,autre_rect.u_max);
v_m = min(self.v_min,autre_rect.v_min);
v_M = max(self.v_max,autre_rect.v_max);
return Rect(u_m,u_M,v_m,v_M,self.w,self.direction);
#Determination of the direction of the initial surface, then compute the extreme coordinates of the axis (the chosen axis depends on the direction)
if(len(Xs)==1):
direction = "X";
u_min = min(Ys);
u_max = max(Ys);
v_min = min(Zs);
v_max = max(Zs);
w = Xs[0];
u_range = Ys;
v_range = Zs;
elif(len(Ys)==1):
direction = "Y";
u_min = min(Xs);
u_max = max(Xs);
v_min = min(Zs);
v_max = max(Zs);
w = Ys[0];
u_range = Xs;
v_range = Zs;
else:
direction = "Z";
u_min = min(Xs);
u_max = max(Xs);
v_min = min(Ys);
v_max = max(Ys);
w = Zs[0];
u_range = Xs;
v_range = Ys;
#Creation of the initial rectangles.
liste_rect = [];
for i in range(len(u_range)-1):
for j in range(len(v_range)-1):
new_rect = Rect(u_range[i],u_range[i+1],v_range[j],v_range[j+1],w,direction); #creation of a Rect that might be contained in the surface
if(new_rect.contenu(polyg)): #if it is indeed inside the surface
liste_rect.append(new_rect); #we add it to the list
#Fusion of all the Rect
i = 0 #index of the Rect we are currently looking at
while(True): #Nota : please don't mess with the break statements...
#Break condition : we stop if we looked to all the Rect in the list (i.e. currently looking to the last Rect)
if(i == len(liste_rect)):
break;
rect_courant = liste_rect[i]; #Current Rect
indice = -1; #Initialization of index of a potential Rect to merge with current Rect
#Try to find a Rect to merge with the current rect
for j in range(i+1,len(liste_rect)): #for each Rect in the list that is not the current rect
if(rect_courant.fusionnable(liste_rect[j])): #if the two Rect are mergeable, we keep the index and we get out of this for loop
indice = j;
break;
#If we did not find anything, we go to the next Rect
if(indice==-1):
i = i+1;
continue;
#If we did find something, we merge the two Rect and we delete the two old Rect from the list
liste_rect[i] = rect_courant.fusion(liste_rect[j]);
liste_rect.pop(j);
#And we go back to the very first Rect (we might have created a Rect that is mergeable)
i = 0;
#Initialisation of the output (list of all the sub-surfaces
resultat = []
for i in range(len(liste_rect)):
resultat.append(Surface.ByPatch(PolyCurve.ByPoints([liste_rect[i].pt1,liste_rect[i].pt2,liste_rect[i].pt3,liste_rect[i].pt4], True)))
OUT = resultat