Finding cells in a set of lines

Hello @Alien something here should work in that case…

Cells.dyn (47.8 KB)

and damn great node this Dataremember

2 Likes

DataRemember is a good node :slight_smile:

That solution is a little bespoke though? If the lines were slightly different it’d not work?

Something to try:

  1. Create a polycurve of each curve by using a Polycurve.ByThickeningCurve node with minimal thickenss, then patch each polycurve into a surface, and union them into one polysurface.

Next get the bounding box of all the thickened curves, and extract a rectangular surface from that.

Then use a Surface.Difference to remove the polysurface from the rectangle. The resulting shape should somewhat look like the cells, but with a gap between each cell.

Take the points if each surface, and find the nearest point from the original intersection points to each. Prune the duplicates and build a polycurve from that.

I think that would be the cells.

1 Like

Wouldn’t you get the bit with the blue ?

image

Well I was thinking of some kinda recursion … some tree thing…
So start at point 0 and go to either pt1 or pt6 … and keep going until you end up at the start (no point can be visited twice)…

image

But then I thought @sovitek’s solution looks right …

Seems like it was messing up for me as there was a duplicate curve for some reason.

I’m gunna see if this works on other shapes.

image
Area isn’t perfect…but it’s close

Just realised it won’t work if there’s an erroneous line that doesn’t form a loop that’s over X length… So I’m gunna change the filter by length bit to filter by, “are both ends touching something” :slight_smile:

Hi,

+1 to create room boundary lines, then create rooms at current level, get Areas and restore everything

import clr
import sys
import System
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

def decoTransactionGp(func):
    def wrapper(*args, **kwargs):
        tg = TransactionGroup(doc, func.__name__)
        tg.Start()
        ret = func(*args, **kwargs)
        tg.RollBack() # or Commit()
        tg.Dispose()
        return ret      
    return wrapper  
    
@decoTransactionGp
def get_Area_by_contourLines(ds_input_lines, scale):
    ds_out_lines = []
    current_view = doc.ActiveView
    current_lvl = current_view.GenLevel
    current_phase = doc.GetElement(current_view.get_Parameter(BuiltInParameter.VIEW_PHASE).AsElementId())
    # create sketch plane and RoomBoundaryLines
    t1 = Transaction(doc, "temp")
    t1.Start()
    skP = SketchPlane.Create(doc,current_lvl.Id)
    cArray = DB.CurveArray()
    for c in ds_input_lines:
        plane = DS.Plane.ByOriginNormal(c.PointAtParameter(0.5), Vector.ZAxis())
        c_scale = c.Scale(plane, scale, scale, 1)
        pta = c_scale.StartPoint.ToXyz()
        ptb = c_scale.EndPoint.ToXyz()
        # move line  to the current level Elevation
        line = DB.Line.CreateBound(XYZ(pta.X, pta.Y, current_lvl.ProjectElevation), 
                                    XYZ(ptb.X, ptb.Y, current_lvl.ProjectElevation))
        cArray.Append(line)
        ds_out_lines.append(line.ToProtoType())
    #
    roomLines = doc.Create.NewRoomBoundaryLines(skP, cArray, current_view)
    t1.Commit()
    # create rooms
    t2 = Transaction(doc, "temp")
    t2.Start()
    roomIds = doc.Create.NewRooms2(current_lvl, current_phase)
    t2.Commit()
    # get Area
    lst_room_Areas = ["Area : {:.3f}m2".format(doc.GetElement(xId).Area * 0.09290304) for xId in roomIds]
    return lst_room_Areas, ds_out_lines

toList = lambda x : x if hasattr(x, '__iter__') else [x]

ds_lines = toList(IN[0])
scale = IN[1]
TransactionManager.Instance.ForceCloseTransaction()
OUT = get_Area_by_contourLines(ds_lines, scale)
5 Likes

Might. But you can set a maximum distance for the closest point to prevent most of those.

Ideally we would build a vector based fill algorithm, but that would take longer to build a working model for than I currently have. Just too many edge cases in each setup.

yes it was just a quick example it could work in your situation I think it will be difficult to make one that will work in all cases, the problem is there are some split, overlapping curves… in the real world I would probably just try to fix this in the source file…but it depends on what it will be used for, is it for rooms?
PS even Topologic toolkit cant work work in all situations…so i guees the best is the avesome solution from @c.poupin with rooms

Well, my try) Remember to replace all you can with dictionaries, if you have big data projects.


Cells.dyn (37.9 KB)

1 Like

yes offcaurse thats the way @Vladimir :wink: :wink:

I was thinking GEAs rather than rooms…
So the lines above would represent an upper floor of a building with an outside balcony with a parapet.

I’d like to learn how to get the graphic display into a clickable pop-up too. :smiley:
The user interface on Dynamo player isn’t always that user friendly imo.

1 Like

3 posts were merged into an existing topic: Extending lines