# How to place family Instances according to the levels below them in python

Hello everyone

This topic is related to the two preor ones How to classify unsorted levels name and Levels with python in which I prefer to use Python to place my family istances in their corresponding levels, so I’ve two cases relating to my total height H_Total in which I should place either one (Fut1) or both of them (Fut1 and Fut2) according the Heigh levels H_Shaft and H_2 by taking the following condition into consideration:

If H_Total % H_Shaft = 0 (So only the instance Fut1 is duplicated to the last level)

else H_2 ≠ 0 (so the instance Fut2 should be placed to the last level)
(Note: H_2 is the remaing Height from the made division H_Total / H_Shaft )

1. Since each instanes is related to its below level, in the case where H_2 ≠ 0 I always end up with one extra instance (Fut1)

2. In addition to duplicating , I should rotate the even ones by 180 degrees as shown in the reference below but they become miss placed because their point location is not in the center, so How can I set it to the center to avoid this issue

Please chek my script , dyn file and Revit file below

``````import sys
import clr
import math
from Autodesk.DesignScript.Geometry import *
import Revit
from Revit.Elements import *

R_exter_Shaft = IN[0]
Thk_Shaft = IN[1]
R_inter_Shaft = R_exter_Shaft - Thk_Shaft
H_Total = IN[2]
H_Shaft = IN[3]
Thk_Slab = IN[4]
H_1 = H_Shaft - Thk_Slab
Family_Cat = IN[5]
Family_Path = IN[6]
Material = IN[7]
Family1_name = 'Shaft1'
Family2_name = 'Shaft2'
Long_Trape = 0.8
angle_Trape = math.degrees(math.atan((Long_Trape/2) / R_inter_Shaft))

# Set Levels_List

if H_Total % H_Shaft > 0:
H_Level = [ i * H_Shaft + H_Shaft for i in range(0, int(H_Total //H_Shaft))]

#compute the remaining Height H_2 from the divison (H_Total / H_Shaft)
H_2 = H_Total - H_Level[-1]
else:
H_Level = [ i * H_Shaft + H_Shaft for i in range(0, int(H_Total //H_Shaft) - 1)]
H_2 = 0
#H_Level.insert(len(H_Level),H_Total)
H_Level.insert(0,0)

#Shaft1_Profil
lst1 = []
Pt1 = Point.ByCoordinates( R_exter_Shaft, 0, -Thk_Slab)
lst1.append(Pt1)
Pt2 = Point.ByCoordinates( R_exter_Shaft, 0, H_1)
lst1.append(Pt2)
Pt3 = Point.ByCoordinates( R_inter_Shaft , 0, H_1)
lst1.append(Pt3)
Pt4 = Point.ByCoordinates( R_inter_Shaft , 0, -Thk_Slab)
lst1.append(Pt4)
vector = Vector.ByCoordinates(0, 0, 1)
Center_pt = Point.ByCoordinates(0, 0, 0)
Shaft1_Profil = Polygon.ByPoints(lst1)
Shaft1 = Solid.ByRevolve(Shaft1_Profil, Center_pt, vector, 0, 360)

#Shaft2_Profil
lst2 = []
Pt_1 = Point.ByCoordinates( R_exter_Shaft, 0, -Thk_Slab)
lst2.append(Pt_1)
Pt_2 = Point.ByCoordinates( R_exter_Shaft, 0, H_2)
lst2.append(Pt_2)
Pt_3 = Point.ByCoordinates( R_inter_Shaft , 0, H_2)
lst2.append(Pt_3)
Pt_4 = Point.ByCoordinates( R_inter_Shaft , 0, -Thk_Slab)
lst2.append(Pt_4)
vector = Vector.ByCoordinates(0, 0, 1)
Center_pt = Point.ByCoordinates(0, 0, 0)
Shaft2_Profil = Polygon.ByPoints(lst2)
Shaft2 = Solid.ByRevolve(Shaft2_Profil, Center_pt, vector, 0, 360)

Slab = Surface.Thicken(Slab_Profil, -Thk_Slab, bool(0))

# opening profil to be subtract from the slab
Trape_arc = Arc.ByCenterPointRadiusAngle(Center_pt, R_inter_Shaft, -angle_Trape, angle_Trape, vector )
Pt1 = Trape_arc.StartPoint
Pt2 = Trape_arc.EndPoint
Pt3 = Pt1.Translate(-Long_Trape)
Pt4 = Pt2.Translate(-Long_Trape)
Line1 = Line.ByStartPointEndPoint(Pt3, Pt4)
Line2 = Line.ByStartPointEndPoint(Pt3, Pt1)
Line3 = Line.ByStartPointEndPoint(Pt4, Pt2)

Profil_Trape = Surface.ByPatch(PolyCurve.ByJoinedCurves([Line1, Line2, Trape_arc, Line3]))
Trape = Surface.Thicken(Profil_Trape, Thk_Slab, bool(0))

Finale_Slab = Solid.Difference(Slab, Trape)

# Shaft1 geometry and Family Type
lst3 = [Shaft1, Finale_Slab]
Final_Shaft1 = Solid.ByUnion(lst3)
Final_Shaft1 = Geometry.Scale(Final_Shaft1, 0.3048)
Final_Shaft1 = FamilyType.ByGeometry(Final_Shaft1, Family1_name, Family_Cat, Family_Path, Material, 'a')

# Shaft2 geometry and Family Type
lst4 = [Shaft2, Finale_Slab]
Final_Shaft2 = Solid.ByUnion(lst4)
Final_Shaft2 = Geometry.Scale(Final_Shaft2, 0.3048)
Final_Shaft2 = FamilyType.ByGeometry(Final_Shaft2, Family2_name, Family_Cat, Family_Path, Material, 'a')

# create Revit Levels
k = 0
Niv = []
for i in H_Level:
k += 1
Lev = Level.ByElevationAndName(i, 'Niveau ' + str(k))
Niv.append(Lev)
print(Lev)

H_Level.sort(reverse=True)

#create and place family Instances Fut1 and Fut2 in their corresponding levels
Fut = []
for i, j in zip(Niv, H_Level):
Fut1 = FamilyInstance.ByPointAndLevel(Final_Shaft1, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), i )
H_offset = j
print(Fut1)
Fut.append(Fut1)
if H_offset < H_Shaft:
Fut2 = FamilyInstance.ByPointAndLevel(Final_Shaft2, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), i )
print(Fut2)
Fut.append(Fut2)
Fut = [FamilyInstance.SetRotation(i, 180) for count, i in enumerate(Fut) if count % 2 == 1]
OUT = Fut
``````

here an exemple what I’m looking for

Shaft_python.dyn (25.1 KB)
Shaft_test.rvt (3.5 MB)

Thanks.

1. It’s probably just as easy to check the top level condition after all the levels have been iterated (rather than within the python node). Get the second to last offset remainder (since the last will always be 0) and use that to determine whether the second family is needed or not. Add it to the list if so, and then continue.

2. This question was asked (and I thought answered) in the first post. Please do not duplicate questions. Same thing as before, if you feel like this still hasn’t been answered then it needs its own thread. One primary problem per thread.

@Nick_Boyts

it’s so easy for you that it becomes difficult for me
I’m completely lost (since I learned python I had problem with the while loop and there’s always a trick that not work for me)
I always have the folowing issue:

1. If the offset remainder H_2 = 0 my instances are created correctly but the last level is missed.

2. If the offset remainder H_2 ≠ 0 I always end up with one extra instance (Shaft1 ) and the second instance (Shaft2 ) is out of level !!

Please check my script and tell me what’s wrong?

``````import sys
import clr
import math
from Autodesk.DesignScript.Geometry import *
import Revit
from Revit.Elements import *

R_exter_Shaft = IN[0]
Thk_Shaft = IN[1]
R_inter_Shaft = R_exter_Shaft - Thk_Shaft
H_Total = IN[2]
H_Shaft = IN[3]
Thk_Slab = IN[4]
H_1 = H_Shaft - Thk_Slab
Family_Cat = IN[5]
Family_Path = IN[6]
Material = IN[7]
Family1_name = 'Shaft1'
Family2_name = 'Shaft2'
Long_Trape = 0.8
angle_Trape = math.degrees(math.atan((Long_Trape/2) / R_inter_Shaft))

# Set Levels_List
n = math.floor(H_Total / H_Shaft)
if H_Total % H_Shaft > 0:
H_2 = H_Total - n * H_Shaft
else:
H_2 = 0

#Shaft1_Profil
lst1 = []
Pt1 = Point.ByCoordinates( R_exter_Shaft, 0, -Thk_Slab)
lst1.append(Pt1)
Pt2 = Point.ByCoordinates( R_exter_Shaft, 0, H_1)
lst1.append(Pt2)
Pt3 = Point.ByCoordinates( R_inter_Shaft , 0, H_1)
lst1.append(Pt3)
Pt4 = Point.ByCoordinates( R_inter_Shaft , 0, -Thk_Slab)
lst1.append(Pt4)
vector = Vector.ByCoordinates(0, 0, 1)
Center_pt = Point.ByCoordinates(0, 0, 0)
Shaft1_Profil = Polygon.ByPoints(lst1)
Shaft1 = Solid.ByRevolve(Shaft1_Profil, Center_pt, vector, 0, 360)

#Shaft2_Profil
lst2 = []
Pt_1 = Point.ByCoordinates( R_exter_Shaft, 0, -Thk_Slab)
lst2.append(Pt_1)
Pt_2 = Point.ByCoordinates( R_exter_Shaft, 0, H_2)
lst2.append(Pt_2)
Pt_3 = Point.ByCoordinates( R_inter_Shaft , 0, H_2)
lst2.append(Pt_3)
Pt_4 = Point.ByCoordinates( R_inter_Shaft , 0, -Thk_Slab)
lst2.append(Pt_4)
vector = Vector.ByCoordinates(0, 0, 1)
Center_pt = Point.ByCoordinates(0, 0, 0)
Shaft2_Profil = Polygon.ByPoints(lst2)
Shaft2 = Solid.ByRevolve(Shaft2_Profil, Center_pt, vector, 0, 360)

Slab = Surface.Thicken(Slab_Profil, -Thk_Slab, bool(0))

# opening profil to be subtract from the slab
Trape_arc = Arc.ByCenterPointRadiusAngle(Center_pt, R_inter_Shaft, -angle_Trape, angle_Trape, vector )
Pt1 = Trape_arc.StartPoint
Pt2 = Trape_arc.EndPoint
Pt3 = Pt1.Translate(-Long_Trape)
Pt4 = Pt2.Translate(-Long_Trape)
Line1 = Line.ByStartPointEndPoint(Pt3, Pt4)
Line2 = Line.ByStartPointEndPoint(Pt3, Pt1)
Line3 = Line.ByStartPointEndPoint(Pt4, Pt2)

Profil_Trape = Surface.ByPatch(PolyCurve.ByJoinedCurves([Line1, Line2, Trape_arc, Line3]))
Trape = Surface.Thicken(Profil_Trape, Thk_Slab, bool(0))

Finale_Slab = Solid.Difference(Slab, Trape)

# Shaft1 geometry and Family Type
lst3 = [Shaft1, Finale_Slab]
Final_Shaft1 = Solid.ByUnion(lst3)
Final_Shaft1 = Geometry.Scale(Final_Shaft1, 0.3048)
Final_Shaft1 = FamilyType.ByGeometry(Final_Shaft1, Family1_name, Family_Cat, Family_Path, Material, 'a')

# Shaft2 geometry and Family Type
lst4 = [Shaft2, Finale_Slab]
Final_Shaft2 = Solid.ByUnion(lst4)
Final_Shaft2 = Geometry.Scale(Final_Shaft2, 0.3048)
Final_Shaft2 = FamilyType.ByGeometry(Final_Shaft2, Family2_name, Family_Cat, Family_Path, Material, 'a')

lst = []
Lev = []
Shaft = []

currentHeight = 0
i = 1
while currentHeight < H_Total:
newLevel = Level.ByElevationAndName(currentHeight, "Level " + str(i) + " (" + str(currentHeight) +")")
print(newLevel)
Shaft1 = FamilyInstance.ByPointAndLevel(Final_Shaft1, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), newLevel )
Lev.append(newLevel)
lst.append(H_Total - currentHeight)
Shaft.append(Shaft1)
i += 1
currentHeight += H_Shaft

if currentHeight != H_Total:
newLevel = Level.ByElevationAndName(H_Total, "Level " + str(i) + " (" + str(H_Total) +")")
print(newLevel)
Shaft2 = FamilyInstance.ByPointAndLevel(Final_Shaft2, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), newLevel )
Lev.append(newLevel)
Shaft.append(Shaft2)
#lst.append(0)

OUT = Shaft
``````

Thanks.

That’s why it’s recommended to go step by step instead of trying to work everything out all at once. It becomes too difficult to determine where or what is the actual problem with the logic.

At this point it would be much easier if you could provide the dyn file and a working example Revit file so we can just run what you have and look at it instead of trying to work through all of the python that you’re unsure of.

1 Like

@Nick_Boyts

here my dyn and Revit files

Shaft_exemple.dyn (23.1 KB)
Shaft_example.rvt (3.5 MB)

Thanks.

You also need to include the template file. Everything that’s needed to run your graph needs to be included and correctly setup so that we can just open the file and run.

It also seemed like some materials were missing. Getting the material by name instead of index is much safer.

@Nick_Boyts

How can I added template file?
I used the default Revit Structural template
(You can open it with structural template) it’s a simple example that I used.

The same thing for material (you can choose anyone from concrete material)

Thanks.

Sorry, the family template file. We don’t have the family.

This is what we’re talking about when we say we need all the information. If you give us something that doesn’t match or doesn’t work we don’t know what it should do or how to fix it. You need to provide all the information so that we don’t have these kinds of situations or provide us with the information to work around them. It’s on you to provide us with a working version of your graph if you want us to test it ourselves.

1 Like

@Nick_Boyts

Sorry for this question:
I used purge button to purge unused elements in my model, so How to keep the family template ?
( The family template I used is metric generic model)

Thanks.

If it’s completely unchanged then just tell us that and that we need to point to our own copy. If you’ve done anything to it for this specific scenario then we’ll need a copy of the rft.

Look at FamilyInstance.ByPointsLevelsBatch from the great Springs package. Maybe it will help.

I think what you’re asking for is as follows (please correct me if I’m wrong):

1. Create levels from `0` to `Total Shaft Height` at intervals equal to the `Shaft Unit Height` (but always ending at the `Total Shaft Height` elevation.)
2. Place `Shaft Units` at each level.
3. If the final level floor-to-floor height is less than the `Shaft Unit Height`, place the `Shaft Unit 2` family to match the floor-to-floor height.

Currently, you’re going through floor by floor and tracking how much space you have left. The problem is you’re doing this up to the final level and then checking to see if your remaining space is 0 or not. But at that point, you’ve already gone past the floor where you might need to place the second unit. Instead of checking whether or not the remaining space is 0 (too late) you need to check to see if/when it gets under the unit height. This will tell you you have one floor left and it’s less than the height required, ie. you need to use the other unit. If you get to less than the required height but the remaining value is 0 then you landed perfectly on your total height and don’t need the secondary unit to fill in.

EDIT:
Try something like this…

Python
``````import sys
import clr
import math
from Autodesk.DesignScript.Geometry import *
import Revit
from Revit.Elements import *

TotalHeight = IN[2]
ShaftHeight = IN[3]
levels = []
shafts = []
remainder = []

NumOfLevels = int(math.ceil(TotalHeight / ShaftHeight))

for i in range(NumOfLevels):
currentHeight = i * ShaftHeight

name = "Level " + str(i+1) + " (" + str(currentHeight) +")"
level = Level.ByElevationAndName(currentHeight, name)
levels.append(level)

remainingHeight = TotalHeight - currentHeight
remainder.append(remainingHeight)

if remainingHeight < ShaftHeight:

if remainingHeight != 0:
shafts.append("Shaft2")

name = "Level " + str(i+2) + " (" + str(TotalHeight) +")"
level = Level.ByElevationAndName(currentHeight, name)
levels.append(level)

else:
shafts.append("Shaft1")

OUT = remainder,levels,shafts
``````
2 Likes

@Nick_Boyts

What you said is exactly what I"m looking for
I’ll try your script and see if it gives the desired result

Thanks.

@Nick_Boyts

decidedly this script makes me crazy!!

I tried your script but I get the same issue as I indecated above (I always end up with one extra instance Shaft1 If the offset remainder H_2 ≠ 0)…I’m missing something and I don’t know what !!?

Please Check my dyn and Revit exemple below (I purged my model and I hope that the templete file and the material are included in it. I don’t know how to check this out)

Shaft-modified_exemple.dyn (20.4 KB)
Shaft-modified_example.rvt (2.2 MB)

Thanks.

Please show us each update. It’s not that we don’t believe the issues you’re having, but we can’t do anything about them if you don’t tell us and, more importantly, show us what they are.

1 Like

@Nick_Boyts

The model does open for you?..you simply run the script and you ll see the issue that I’m talking about!!
Ok…here’s what I got

and here my code

``````import sys
import clr
import math
from Autodesk.DesignScript.Geometry import *
import Revit
from Revit.Elements import *

R_exter_Shaft = IN[0]
Thk_Shaft = IN[1]
R_inter_Shaft = R_exter_Shaft - Thk_Shaft
H_Total = IN[2]
H_Shaft = IN[3]
Thk_Slab = IN[4]
H_1 = H_Shaft - Thk_Slab
Family_Cat = IN[5]
Family_Path = IN[6]
Material = IN[7]
Family1_name = 'Shaft1'
Family2_name = 'Shaft2'
Long_Trape = 0.8
angle_Trape = math.degrees(math.atan((Long_Trape/2) / R_inter_Shaft))

# Set Levels_List
n = int(math.ceil(H_Total / H_Shaft))
if H_Total % H_Shaft > 0:
H_2 = H_Total - (n-1) * H_Shaft
else:
H_2 = 0

#Shaft1_Profil
lst1 = []
Pt1 = Point.ByCoordinates( R_exter_Shaft, 0, -Thk_Slab)
lst1.append(Pt1)
Pt2 = Point.ByCoordinates( R_exter_Shaft, 0, H_1)
lst1.append(Pt2)
Pt3 = Point.ByCoordinates( R_inter_Shaft , 0, H_1)
lst1.append(Pt3)
Pt4 = Point.ByCoordinates( R_inter_Shaft , 0, -Thk_Slab)
lst1.append(Pt4)
vector = Vector.ByCoordinates(0, 0, 1)
Center_pt = Point.ByCoordinates(0, 0, 0)
Shaft1_Profil = Polygon.ByPoints(lst1)
Shaft1 = Solid.ByRevolve(Shaft1_Profil, Center_pt, vector, 0, 360)

#Shaft2_Profil
lst2 = []
Pt_1 = Point.ByCoordinates( R_exter_Shaft, 0, -Thk_Slab)
lst2.append(Pt_1)
Pt_2 = Point.ByCoordinates( R_exter_Shaft, 0, H_2)
lst2.append(Pt_2)
Pt_3 = Point.ByCoordinates( R_inter_Shaft , 0, H_2)
lst2.append(Pt_3)
Pt_4 = Point.ByCoordinates( R_inter_Shaft , 0, -Thk_Slab)
lst2.append(Pt_4)
vector = Vector.ByCoordinates(0, 0, 1)
Center_pt = Point.ByCoordinates(0, 0, 0)
Shaft2_Profil = Polygon.ByPoints(lst2)
Shaft2 = Solid.ByRevolve(Shaft2_Profil, Center_pt, vector, 0, 360)

Slab = Surface.Thicken(Slab_Profil, -Thk_Slab, bool(0))

# opening profil to be subtract from the slab
Trape_arc = Arc.ByCenterPointRadiusAngle(Center_pt, R_inter_Shaft, -angle_Trape, angle_Trape, vector )
Pt1 = Trape_arc.StartPoint
Pt2 = Trape_arc.EndPoint
Pt3 = Pt1.Translate(-Long_Trape)
Pt4 = Pt2.Translate(-Long_Trape)
Line1 = Line.ByStartPointEndPoint(Pt3, Pt4)
Line2 = Line.ByStartPointEndPoint(Pt3, Pt1)
Line3 = Line.ByStartPointEndPoint(Pt4, Pt2)

Profil_Trape = Surface.ByPatch(PolyCurve.ByJoinedCurves([Line1, Line2, Trape_arc, Line3]))
Trape = Surface.Thicken(Profil_Trape, Thk_Slab, bool(0))

Finale_Slab = Solid.Difference(Slab, Trape)

# Shaft1 geometry and Family Type
lst3 = [Shaft1, Finale_Slab]
Final_Shaft1 = Solid.ByUnion(lst3)
Final_Shaft1 = Geometry.Scale(Final_Shaft1, 0.3048)
Final_Shaft1 = FamilyType.ByGeometry(Final_Shaft1, Family1_name, Family_Cat, Family_Path, Material, 'a')

# Shaft2 geometry and Family Type
lst4 = [Shaft2, Finale_Slab]
Final_Shaft2 = Solid.ByUnion(lst4)
Final_Shaft2 = Geometry.Scale(Final_Shaft2, 0.3048)
Final_Shaft2 = FamilyType.ByGeometry(Final_Shaft2, Family2_name, Family_Cat, Family_Path, Material, 'a')

levels = []
shafts = []
remainder = []

NumOfLevels = int(math.ceil(H_Total / H_Shaft))
for i in range(NumOfLevels):
currentHeight = i * H_Shaft
name = "Level " + str(i+1) + " (" + str(currentHeight) +")"
level = Level.ByElevationAndName(currentHeight, name)
Shaft1 = FamilyInstance.ByPointAndLevel(Final_Shaft1, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), level )
levels.append(level)
remainingHeight = H_Total - currentHeight
remainder.append(remainingHeight)
if remainingHeight < H_Shaft:
if remainingHeight != 0:
Shaft2 = FamilyInstance.ByPointAndLevel(Final_Shaft2, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), level)
shafts.append("Shaft2")

else:
shafts.append("Shaft1")
OUT = shafts, remainder
``````

Thanks.

It looks like you took my code structure and applied your code to it. That’s a good start, but you’re not looking at where I’m doing certain things. You put everything under the main loop and then ignored the conditions for Shaft1 vs Shaft2. Shaft2 is being created in the right place (where I add my placeholder for Shaft2) but everything for Shaft1 is in the main loop, not where I’m adding the Shaft1 placeholder. You’re also just leaving out other parts of the code that revolve around making sure the top level condition is accurate.

Please spend some time trying to understand what others are trying to show you instead of just copy/pasting and then complaining that it doesn’t work.

1 Like

@Nick_Boyts

reproach accepted from you (I was tired and lacking concentration)

I corrected my mistakes and this time it works, but there is still a trick to fix (The top level is missed If the offset remainder H_2 = 0…in your code too)

Here The part corrected of my code:

``````levels = []
shafts = []
remainder = []

NumOfLevels = int(math.ceil(H_Total / H_Shaft))
for i in range(NumOfLevels):
currentHeight = i * H_Shaft
name = "Level " + str(i+1) + " (" + str(currentHeight) +")"
level = Level.ByElevationAndName(currentHeight, name)
remainingHeight = H_Total - currentHeight
remainder.append(remainingHeight)
if remainingHeight < H_Shaft:
if remainingHeight != 0:
Shaft2 = FamilyInstance.ByPointAndLevel(Final_Shaft2, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), level)
shafts.append("Shaft2")
name = "Level " + str(i+2) + " (" + str(H_Total) +")"
level = Level.ByElevationAndName(H_Total, name)

else:
Shaft1 = FamilyInstance.ByPointAndLevel(Final_Shaft1, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), level )
levels.append(level)
shafts.append("Shaft1")

OUT = shafts, remainder
``````

No idea for my 2nd question here?

Thanks.

Have you looked into why that might be? I did make a minor mistake when dealing with the final level condition. Rather than giving up because the solution you were given doesn’t do exactly what you want it to do, take some time to understand what it’s doing and try to fix it. This is not a forum for requesting other people to do your work for you. Show us that you’re putting in some kind of effort trying to fix your own problem.

As for the rotation of the families, this was already addressed in your first thread. If you’re still having issues you need to start a brand new thread, just like before, and link any pertinent information for addressing the problem.

@Nick_Boyts

Yes I’ve seen this mistake and I’ve fixed it before you asked me for that (see my previous code)
You puted:

``````level = Level.ByElevationAndName(currentHeight, name)
``````

And I Puted the correction:

``````level = Level.ByElevationAndName(H_Total, name)
``````

Who tell you that I’m not putting efforts to understand my problem and that I’m requesting for others to doing my work??..If I not put any effort to fix and understand my problem I wouldn’t even have asked my question !!
I tried to fix the Top level condition in the case were the offset remainder H_2 = 0 by more ways but I still can’t solve the problem…here my last test:

``````levels = []
shafts = []
remainder = []

NumOfLevels = int(math.ceil(H_Total / H_Shaft))
for i in range(NumOfLevels):
currentHeight = i * H_Shaft
name = "Level " + str(i+1) + " (" + str(currentHeight) +")"
level = Level.ByElevationAndName(currentHeight, name)
remainingHeight = H_Total - currentHeight
remainder.append(remainingHeight)
if remainingHeight < H_Shaft:
if remainingHeight != 0:
Shaft2 = FamilyInstance.ByPointAndLevel(Final_Shaft2, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), level)
shafts.append("Shaft2")
name = "Level " + str(i+2) + " (" + str(H_Total) +")"
level = Level.ByElevationAndName(H_Total, name)
else:
name = "Level " + str(i+1) + " (" + str(H_Total) +")"
level = Level.ByElevationAndName(H_Total, name)
else:
Shaft1 = FamilyInstance.ByPointAndLevel(Final_Shaft1, Point.ByCoordinates(-R_exter_Shaft, -R_exter_Shaft, 0), level )
levels.append(level)
shafts.append("Shaft1")

OUT = shafts, remainder
``````

Thanks.