Repeat the process until user click cancel button

Hi all, Good afternoon !

Actually I am looking for loop statement, like I need a python code or dynamo graph to repeat the process until user click cancel button to proceed further.

Basically I am trying to automate the columns placement at every grid intersection points, the moment it places at all the intersecting points, it will ask me which column do I need to select and further what will be the rotation, x-translation and y-translation. So I need to repeat this process until user click cancel button to proceed further. So please let me know how to do that ?

Here is the sample script.

Parametric column.dyn (154.8 KB)

Hello,

could work with an Increment + 3m f.e. example. every rerun places an element.

KR

Andreas

1 Like

Hi @Draxl_Andreas yes I don’t want to repeat like this. I want to it to be like, if the user wants to finish the process he/she may click cancel button to proceed. Hope you got my point.

@Draxl_Andreas I want the same thing but not like this. I want to use some loop statement in python so that I can proceed with further. As many as times I want it to repeat that depends on user when he/she clicks on the ok button or cancel button to proceed further.

Have the graph write out a text/CSV file for whatever the increment is. Use Player and the graph will read the file for the next increment for each Play.

1 Like

Hi @truevis Thanks for your response.

I am actually not getting your point. Can you please elaborate a bit ? in terms of graph or code ?

It’s just a concept. A method for Dynamo to be able to recall what was done or selected previously is to write and read a text file.

Hi, an example just with rotation.
If you want to add more parameters (as X, Y translation), it will be preferable to make a UI Form (Winform or Wpf)
rotate loop

import sys
import clr
import System
clr.AddReference('Microsoft.VisualBasic')
import Microsoft.VisualBasic
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

#import Revit APIUI namespace
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import *


clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

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

TransactionManager.Instance.EnsureInTransaction(doc)
i = 0
while i < 100:
	i += 1
	TaskDialog.Show('Selection', 'Select column to rotate, press Cancel or ECS key to QUIT')
	try:
		ref = uidoc.Selection.PickObject(ObjectType.Element, 'Select column to rotate, press ECS key to quit')
	except Exception :
		break
	elem = doc.GetElement(ref)
	input = Microsoft.VisualBasic.Interaction.InputBox("Enter Rotation in degre", "Rotation", "0", 0, 0)
	if input == "":
		break
	else:
		angle = float(input) * 0.0174533 # convert in radian
		locPt = elem.Location.Point
		axis = DB.Line.CreateUnbound(locPt, XYZ(0,0,1))
		DB.ElementTransformUtils.RotateElement(doc, elem.Id, axis, angle)
		doc.Regenerate()

TransactionManager.Instance.TransactionTaskDone()
OUT = input
6 Likes

Hi @c.poupin Thanks for the solution but something is giving an error as below

image

Can you please tell me why is this so happening ? I just wanted to what is missing ?

Thanks in advance

and also I have mentioned like I wanted to have x translation and y translation both in my UI menu when click on the column. Can you please help me with that ?

This is just an example that works with an element whose location is defined by a point (like columns you mentioned in your original post)

Do you want to try to make your own UI with WinForm?

1 Like

Yes, @c.poupin that script works for me but only the thing is I also want to add x translation and y translation in the same script so that it should ask me the rotational angle, x translation value and y translation value. thanks it. Please help me with that

how to add x translation and y translation into the script ?

import sys
import clr
import System
clr.AddReference('Microsoft.VisualBasic')
import Microsoft.VisualBasic
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

#import Revit APIUI namespace
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
from Autodesk.Revit.UI.Selection import *


clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
uidoc = uiapp.ActiveUIDocument

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

TransactionManager.Instance.EnsureInTransaction(doc)
i = 0
while i < 100:
	i += 1
	TaskDialog.Show('Selection', 'Select column to rotate, press Cancel or ECS key to QUIT')
	try:
		ref = uidoc.Selection.PickObject(ObjectType.Element, 'Select column to rotate, press ECS key to quit')
	except Exception :
		break
	elem = doc.GetElement(ref)
	input = Microsoft.VisualBasic.Interaction.InputBox("Enter Rotation in degre", "Rotation", "0", 0, 0)
	if input == "":
		break
	else:
		angle = float(input) * 0.0174533 # convert in radian
		locPt = elem.Location.Point
		axis = DB.Line.CreateUnbound(locPt, XYZ(0,0,1))
		DB.ElementTransformUtils.RotateElement(doc, elem.Id, axis, angle)
		doc.Regenerate()

TransactionManager.Instance.TransactionTaskDone()
OUT = input

Your request is really very specific, the least you could have done was to explore a solution that I mentioned earlier (wpf or Winform).

Here is a example with Winform (I hope this example will be useful for several users).

image

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

clr.AddReference('RevitAPI')
import Autodesk
import Autodesk.Revit.DB as DB

clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI.Selection import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
import System.Drawing
import System.Windows.Forms
from System.Drawing import *
from System.Windows.Forms import *

class MyForm(Form):
	def __init__(self):
		self.InitializeComponent()
	
	def InitializeComponent(self):
		self._buttonCancel = System.Windows.Forms.Button()
		self._buttonOk = System.Windows.Forms.Button()
		self._label1 = System.Windows.Forms.Label()
		self._label2 = System.Windows.Forms.Label()
		self._label3 = System.Windows.Forms.Label()
		self.numericaNgle = System.Windows.Forms.NumericUpDown()
		self.numericx = System.Windows.Forms.NumericUpDown()
		self.numericy = System.Windows.Forms.NumericUpDown()
		self.numericaNgle.BeginInit()
		self.numericx.BeginInit()
		self.numericy.BeginInit()
		self.SuspendLayout()
		# 
		# buttonCancel
		self._buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
		self._buttonCancel.Location = System.Drawing.Point(12, 201)
		self._buttonCancel.Name = "buttonCancel"
		self._buttonCancel.Size = System.Drawing.Size(110, 40)
		self._buttonCancel.TabIndex = 2
		self._buttonCancel.Text = "Quit"
		self._buttonCancel.UseVisualStyleBackColor = True
		# 
		# buttonOk
		self._buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK
		self._buttonOk.Location = System.Drawing.Point(163, 201)
		self._buttonOk.Name = "buttonOk"
		self._buttonOk.Size = System.Drawing.Size(110, 40)
		self._buttonOk.TabIndex = 2
		self._buttonOk.Text = "Select Column to Apply"
		self._buttonOk.UseVisualStyleBackColor = True
		# 
		# label1
		self._label1.Location = System.Drawing.Point(156, 31)
		self._label1.Name = "label1"
		self._label1.Size = System.Drawing.Size(119, 23)
		self._label1.TabIndex = 3
		self._label1.Text = "Angle (Degre)"
		# 
		# label2
		self._label2.Location = System.Drawing.Point(156, 79)
		self._label2.Name = "label2"
		self._label2.Size = System.Drawing.Size(119, 23)
		self._label2.TabIndex = 3
		self._label2.Text = "X (millimeter)"
		# 
		# label3
		self._label3.Location = System.Drawing.Point(156, 129)
		self._label3.Name = "label3"
		self._label3.Size = System.Drawing.Size(119, 23)
		self._label3.TabIndex = 3
		self._label3.Text = "Y (millimeter)"
		# 
		# numericAngle
		self.numericaNgle.Location = System.Drawing.Point(12, 29)
		self.numericaNgle.Maximum = System.Decimal(System.Array[System.Int32]([1000,0,0,0]))
		self.numericaNgle.Minimum = System.Decimal(System.Array[System.Int32]([1000,0,0,-2147483648]))
		self.numericaNgle.Name = "numericAngle"
		self.numericaNgle.Size = System.Drawing.Size(120, 20)
		self.numericaNgle.TabIndex = 4
		# 
		# numericX
		self.numericx.Location = System.Drawing.Point(12, 77)
		self.numericx.Maximum = System.Decimal(System.Array[System.Int32]([1000,0,0,0]))
		self.numericx.Minimum = System.Decimal(System.Array[System.Int32]([1000,0,0,-2147483648]))
		self.numericx.Name = "numericX"
		self.numericx.Size = System.Drawing.Size(120, 20)
		self.numericx.TabIndex = 4
		# 
		# numericY
		self.numericy.Location = System.Drawing.Point(12, 127)
		self.numericy.Maximum = System.Decimal(System.Array[System.Int32]([1000,0,0,0]))
		self.numericy.Minimum = System.Decimal(System.Array[System.Int32]([1000,0,0,-2147483648]))
		self.numericy.Name = "numericY"
		self.numericy.Size = System.Drawing.Size(120, 20)
		self.numericy.TabIndex = 4
		# 
		# Form9
		self.ClientSize = System.Drawing.Size(295, 261)
		self.FormBorderStyle = FormBorderStyle.FixedSingle
		self.Controls.Add(self.numericy)
		self.Controls.Add(self.numericx)
		self.Controls.Add(self.numericaNgle)
		self.Controls.Add(self._label3)
		self.Controls.Add(self._label2)
		self.Controls.Add(self._label1)
		self.Controls.Add(self._buttonOk)
		self.Controls.Add(self._buttonCancel)
		self.Name = "Form9"
		self.Text = "Change Column Location"
		self.numericaNgle.EndInit()
		self.numericx.EndInit()
		self.numericy.EndInit()
		self.ResumeLayout(False)

TransactionManager.Instance.EnsureInTransaction(doc)
out = []
i = 0
while i < 200:
	i += 1
	objform = MyForm()
	objform.ShowDialog()
	if objform.DialogResult == DialogResult.OK:
		try:
			ref = uidoc.Selection.PickObject(ObjectType.Element, 'Select Column, press ECS key to quit')
		except Exception as ex:
			break
		else:
			elem = doc.GetElement(ref)
			angle = System.Decimal.ToDouble(objform.numericaNgle.Value) * 0.0174533 # convert degree to radian
			x_translate = System.Decimal.ToDouble(objform.numericx.Value) * 0.00328084 # convert millimeter to feet
			y_translate = System.Decimal.ToDouble(objform.numericy.Value) * 0.00328084 # convert millimeter to feet
			locPt = elem.Location.Point
			axis = DB.Line.CreateUnbound(locPt, DB.XYZ(0,0,1))
			DB.ElementTransformUtils.RotateElement(doc, elem.Id, axis, angle)
			DB.ElementTransformUtils.MoveElement(doc, elem.Id, DB.XYZ(x_translate, y_translate, 0))
			doc.Regenerate()
			out.append(elem)
	else:
		break
	objform.Dispose()

TransactionManager.Instance.TransactionTaskDone()
OUT = out

As a reminder, the forum is not a “do your job”
the forum rules (How to get help on the Dynamo forums )
the community guidelines (https://forum.dynamobim.com/faq )

9 Likes

Thanks alot @c.poupin it works for me and I really appriciate the efforts and time you took to give this solution. Thank you once again.

1 Like

can I use
objform.Dialog()
instead of
objform.ShowDialog()
?

because I want user to be able to operate revit in the background. :slight_smile:

Hi,
no, it won’t work

thanks :frowning: