Create curve from column - Different result when column is connected to floor above or absent of floor

Hello all!
Back from a short break from working with revit.
I am creating a code which takes the corners of the top surface and bottom surface and connects a line between them (end goal is to create longitude rebar).
I managed to get to the point where I have a list of points of the bottom and top surface, and I create a python code which creates a list of the top points and bottom points by crossing the X,Y coordinates and the points with smaller Z value goes to the Bot list and the points with greater Z values go to the Top list.
It worked!
But then I tried to add a ceiling on top of the column to test the top point’s values and to my surprise - I now get only two lines…
Attaching the code to the post.
Any idea why this happens?

Column without ceiling result

Column with ceiling result

Python Code

li=IN[0] if isinstance(IN[0],list) else [IN[0]]

Bot=[ ]
Top=[ ]

for point in li:
	for point2 in li:    #Cross point in list against other points in list
		for poi in Bot:    #if point has beened checked previously - flag
			if poi == point:
				flag =1

		if flag==0:
			for poi in Top:    #if point has beened checked previously - flag
				if poi == point:
					flag =1
		if flag:
			continue    #if point has beened flagged - continue to next point
		if point2==point:     #If point is the same being checked - continue
		if point2.X == point.X and point2.Y == point.Y:        #If 2 points have same x, y coordinates
			if point.Z<point2.Z:      #If Z coordinate is smaller - assign to Bot
			else:                     #Else - assign to Top    

OUT = Bot,Top

The python code is coming out a bit broken in the post so I’ll try and explain the beginning:
It receives the list of points in variable “li”. I created a nested for loop which crosses the point in the list to the rest of the points in the list.

to compare points is better to use Geometry.DistanceTo() or Geometry.IsAlmostEqualTo() method instead of check equality
an example

import sys
import clr
from Autodesk.DesignScript.Geometry import *
def sortFunc(ptb):
	global lstPtsA
	ptB = Point.ByCoordinates(ptb.X, ptb.Y, 0)
	for idx, pta in enumerate(lstPtsA):
		ptA = Point.ByCoordinates(pta.X, pta.Y, 0)
		if ptA.DistanceTo(ptB) < 0.01:
			return idx
	return float('inf')
lstPts = IN[0]

lstPts = sorted(lstPts, key = lambda x : x.Z)
lstPtsA = lstPts[: len(lstPts) / 2]
lstPtsB = lstPts[len(lstPts) / 2 : ]
# sort lstPtsB by lstPtsA coordinnates
lstPtsB.sort(key = lambda x : sortFunc(x))
# draws lines
DSlines = [Line.ByStartPointEndPoint(pta, ptb) for pta, ptb in zip(lstPtsA, lstPtsB)]
OUT = DSlines
1 Like

If the columns are square, you may be better off with a Topology.Edges into an Edge.CurveGeometry node. You can then filter out curves by length relative to the columns overall height.

If they are round, Curve.PointAtParameter followed by a Geometry.ClosestPointTo would work well.

1 Like

Well, I need to offset the curves inward, that’s why I took the top and bottom surface, offset them inwards, created points and then connecting them with a line. Do you think this is an inferior solution?
Any understanding though, why the code would give me different results between when there is a ceiling or not? After all, in both cases I feed the code with the same amount of points…

Code look great but unfortunately, a little advanced for me…
I understand that you sort the list at first based on the Z value, then chop it in to two list: the first half including the Z=0 in one list and the other that includes the second half. The sortFunc isn’t totally clear to me. I understand that you call on it with the list of lstPtsB and when you declare Global lstPtsA that basically calls that list(did I get it right?). After that I lost you when you set each Z value for both points to 0…
But do you understand why my code gives different result between the two cases? After all, in both cases it is fed with 8 points with two sets of Z values…

Not inferior - just putting an alternative out there. You could also take the thin shell of the solids, or translate the edges after the fact.

I guess in your list of points, for each pair of points there should be the X and Y coordinates which are not strictly equal

the pointA == pointB operation does not compare geometry, but entities (hash). Although this works for points, it will not work for other types of geometry

The code is to iterate through a list while iterating at a second level and compare the points coordinates. If in the second layer pointA==pointB, which means that it is comparing the same object (which is pointless) I want it to continue and compare the next object. That was the intention of the specific line of code.
The next if statement compares the X,Y coordinate of both points, which if true, the point are in line with each other. That’s why it is weird that the ceiling alters the result ending with only two point in line with each other…

Thanks, I’ll try offsetting the surfaces to get the intersection curves.