PyRevit Plug-in (Suddivide surface in triangles and rectangles)

Hello,
Im trying to create a pyRevit plugin. I would like to create a python script where i can take a surface (from areas/rooms) and split its area in rectangles and triangle (if necessary i.e. curve/inclinated wall/room boundary/area boundary, ecc..). Is there some fromulas or criteria/ articles/ sites who can help me to create this program concept?
Thanks

No need for PyRevit, but if you really want to use those tools the forums you linked would be best.

If you want to stay in the Dynamo ecosystem Look into algorithms for largest inscribed rectangle.

Hi, check out this great post of @Vikram_Subbaiah (code in DesignScript)

Here is a solution that divides the polygon into rectangular subregions by extending horizontal and vertical lines from the vertices using shapely.

import clr
clr.AddReference('ProtoGeometry')
import Autodesk.DesignScript.Geometry as DS

import numpy as np
from itertools import combinations
from shapely import affinity
from shapely.geometry import Polygon, box
from shapely.ops import unary_union
from shapely.prepared import prep


def convert_poly_toDSPoly(geo):
    pts = [DS.Point.ByCoordinates(x, y, zvalue) for x, y in geo.exterior.coords]
    try:
        return DS.Polygon.ByPoints(DS.Point.PruneDuplicates(pts))
    except:
        return None


def get_largest_internal_rect(poly):
    rings = [poly.exterior] + list(poly.interiors)
    coords = np.vstack([np.asarray(r.coords)[:, :2] for r in rings])
    xs, ys = map(np.unique, coords.T)
    pp = prep(poly)

    rects = (
        box(x1, y1, x2, y2)
        for x1, x2 in combinations(xs, 2)
        for y1, y2 in combinations(ys, 2)
    )
    return max((r for r in rects if pp.contains(r)), key=lambda r: r.area, default=None)


def get_polys(geo):
    if geo.is_empty:
        return []
    if geo.geom_type == 'Polygon':
        return [geo]
    return [g for g in getattr(geo, 'geoms', []) if g.geom_type == 'Polygon']


def subtractive_decomposition(poly, max_rooms=15):
    remaining, rectangles = poly, []

    for _ in range(max_rooms):
        if remaining.is_empty or remaining.area < .01:
            break

        pieces = sorted(get_polys(remaining), key=lambda p: p.area, reverse=True)
        if not pieces:
            break

        target, others = pieces[0], pieces[1:]
        rect = get_largest_internal_rect(target)
        ok = rect is not None and rect.area >= .01

        rectangles.append(rect if ok else target)
        rest = [target.difference(rect)] if ok else []
        remaining = unary_union(rest + others) if rest or others else Polygon()

    return rectangles

ds_polygon = IN[0]
v = DS.Vector.XAxis()
cs = DS.BoundingBox.ByMinimumVolume([ds_polygon]).ContextCoordinateSystem
angle = v.AngleWithVector(cs.XAxis) * (1 if v.Cross(cs.XAxis).Z > 0 else -1)
zvalue = ds_polygon.Points[0].Z

poly = Polygon([(p.X, p.Y) for p in ds_polygon.Points]).buffer(0)
poly = affinity.rotate(poly, -angle, origin=(0, 0))
# grid-based search algo
final_decomposition = subtractive_decomposition(poly)
final_decomposition = [affinity.rotate(x, angle, origin=(0, 0)) for x in final_decomposition]

OUT = [convert_poly_toDSPoly(x) for x in final_decomposition if x.geom_type == 'Polygon' and len(x.exterior.coords) <= 5]