Creating wall and ground floor based on a curve

Hello,

I am currently in the process of extracting a floor plan from an SVG file. So far, I have successfully obtained the element coordinates. However, I am unsure about the most effective approach to reconstruct a 3D model and assign the appropriate wall types.

In my initial attempt, I calculated the average point between two corner points and used the extracted coordinates to create a polycurve. However, I have noticed that with more complex floor plans, the calculated average points are not precise enough to generate an accurate 3D model as lines are getting not straight.

It is crucial for me to develop a universal script that does not require manual adjustment of the coordinates, as I intend to apply it to other SVG files as well.

If anyone has any suggestions or advice, I would greatly appreciate it!

Here the list:
[[193.19, 232.83], [732.94, 232.83], [756.94, 208.83], [169.1, 208.83]]
[[732.94, 232.83], [732.94, 955.71], [756.94, 979.71], [756.94, 208.83]]
[[732.94, 955.71], [81.79, 955.71], [57.79, 979.71], [756.94, 979.71]]
[[81.79, 955.71], [81.79, 645.21], [57.79, 621.21], [57.79, 979.71]]
[[81.79, 645.21], [194.79, 645.21], [170.7, 621.21], [57.79, 621.21]]
[[194.79, 645.21], [193.19, 232.83], [169.1, 208.83], [170.7, 621.21]]
[[237.16, 979.71], [237.16, 1105.4], [247.16, 1095.4], [247.16, 979.71]]
[[237.16, 1105.4], [419.1, 1105.4], [409.1, 1095.4], [247.16, 1095.4]]
[[419.1, 1105.4], [419.1, 979.71], [409.1, 979.71], [409.1, 1095.4]]

Python Code to create coords:

input_list = IN[0]

def extract_coordinates(input_list):
    x_coordinates = []
    y_coordinates = []

    for sublist in input_list:
        for coordinate in sublist:
            x_coordinates.append(coordinate[0])
            y_coordinates.append(coordinate[1])

    return x_coordinates, y_coordinates

x_coords, y_coords = extract_coordinates(input_list)

OUT = x_coords #y_coords in another python block

Thank you.


Hey,

I’m not an expert, but maybe look into Alpha shapes / Concave hull / Convex hull?

Hope that helps,

Mark

1 Like

Hello. Thank you for your reply.
I have attached some pictures which might help clarify my problem.
I am extracting coordinates from the SVG file in order to create a 3D model. So far, I have successfully generated external and internal walls based on these coordinates. However, I am facing some issues with these solids. Firstly, I am unable to create specific walls that I can select in Revit, such as those made of a particular material (pic4). Additionally, I am unable to place windows within the solids.

I have included the original SVG file and some pictures of my script for reference.




Might be a better way to pull the data out of the SVG, but I’m not sure. Can you post the dyn you’re using so community members can brainstorm and review with the larger context?

Hello,

I have attached the SVG file in the Drive folder along with the corresponding text file that displays the extracted coordinates from the SVG. You can access them through this link: Google Drive Folder.

The first image showcases a script that extracts the coordinates from the text file named “Wall_External_points.txt” located in the Drive folder. Every polygon with 4 coordinates represents a wall. Afterward, I mirror the coordinates and scale them down by dividing them by 40.

The second image illustrates the generated coordinates:

My current objective is to create walls using the “Wall.ByCurveAndHeight” node. Later i also want to add internal walls and windows etc.

Thank’s everyone for helping.

Hello,

I’ve successfully created middle points and established lines between specific points. Using these lines, I’ve managed to form walls. However, I’m currently facing an issue where certain walls are not connected, as illustrated in the following picture:

Thank’s again.

Looks like every wall should end and start when touching another wall.

I’m remote and typing this on my phone, but the logic seems sound. Once you have the list of curves…

For index in range(curves): #build a loop as long as the list of curves
    crv = curves.pop(0) #pull a curve from the start of the list
    srfs = [Curve.Extrude(j,Vector.ZAxis()) for j in curves] #extrude the curves on the Z axis into a surface 
    psrf = PolySurface.ByJoinedSurfaces(srfs) #build a polysurface of the extruded surfaces 
    startTest = crv.StartPoint.DoesIntersect(psrf) #test if the start point touches any of the other surfaces 
    if not startTest: crv.ExtendStart(wallWidth/2) #if the start point didn’t intersect anything, extend the point by 1/2 the wall width
    endTest = crv.EndPoint.DoesIntersect(psrf) #test if the end point touches the polysurface
    if not endTest: crv.ExtendStart(wallWidth/2) # if not extend the curve by 1/2 the wall width
    curves.append(crv) #put the potentially modified curve back into the list.

If there might be ‘ends’ which don’t want to extend, test the renovated end point and if that still doesn’t hit you can revert the extension.

Thanks a lot!
I solved the whole thing myself. By implementing a Python script, I was able to create connections between points and lines when the distance falls below a certain threshold.

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

# Eingabeparameter
punkte = IN[0]
abstand = IN[1]
linien = IN[2]

# Leere Liste fĂźr verbundene Punkte
verbundene_punkte = []

# Funktion zum Berechnen des Abstands zwischen einem Punkt und einer Linie
def abstand_zu_linie(punkt, linie):
    projizierte_position = linie.ClosestPointTo(punkt)
    abstand = punkt.DistanceTo(projizierte_position)
    return abstand

# Punkte mit den Linien verbinden
for punkt in punkte:
    for linie in linien:
        if abstand_zu_linie(punkt, linie) <= abstand and abstand_zu_linie(punkt, linie) > 0:
            verbundene_punkte.append(Line.ByStartPointEndPoint(punkt, linie.ClosestPointTo(punkt)))

# Ausgabe der verbundenen Linien
OUT = verbundene_punkte