Cannot get Wire.SetVertex(Index, XYZ) to work

Hi guys, as the title is saying, this look so easy to achieve, yet i simply cannot get it to work.

This is how it looks in C#

C#

public void SetVertex(
	int index,
	XYZ vertexPoint
)

I create a wire using vertices extracted from a PolyCurve , and connect the wire to 2 devices.

All is well, except the 2 end vertices of the wire (first and last one) jump around when the wire is connected to a device so i have to manually drag them in place…which is bad…

SO, i KNOW the x,y,z coordinates of where I would like these end vertices to be: Start and End Point of the PolyCurve that generates the vertices for the wire when it is created.

So i feed this wire and new values for the Start and End vertices of the wire which are close the the Start and End point of the PolyCurve, by adding “1” to x and y (z i leave alone).

It is “working” in the sense that the end vertices are being moved, but they are moved very faaaaaaaaaaaaaaaar away from the x,y,z location of where they are supposed to be. (which again - is close to the Start and End point of the PolyCurve that generated the wire in the first place…)

Please, anyone, what am I doing wrong? Am I not using the same UCS??? Why is it working ok for setting the correct position of vertices when the wire is created but then interpreted so wrong when i want to reposition the end vertices of the wire???

And a picture of the result:

The Code, which for the most part i got from this forum:
*the IN[1] to IN[6] are …lists of 1 element… so that’s why i use [0] to get the only value from the list…

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


clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('System')
from System.Collections.Generic import List

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)


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

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


clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB.Electrical import *
import System

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

from System.Collections.Generic import *


wire=UnwrapElement(IN[0])
newStartX = IN[1]
#the above X value has 1 already added to it, then rounded
newStartY = IN[2]
newStartZ = IN[3]
newEndX = IN[4]
#the above X value has 1 already added to it, then rounded
newEndY = IN[5]
newEndZ = IN[6]

TransactionManager.Instance.EnsureInTransaction(doc)

errorReport=[]
try:
	
	
	#________# ASTA AR TREB SA MEARGA
	xyzStart = Autodesk.Revit.DB.XYZ(newStartX[0],newStartY[0],newStartZ[0])
	#wire.SetVertex(0, XYZ(0,0,0))
	wire.SetVertex(0,xyzStart)
	
	
	#________# ASTA AR TREB SA MEARGA
	xyzEnd = Autodesk.Revit.DB.XYZ(newEndX[0],newEndY[0],newEndZ[0])
	lastvertIndex = wire.NumberOfVertices - 1
	wire.SetVertex(lastvertIndex, xyzEnd)
	#wire.SetVertex(lastvertIndex, XYZ(newEndX,newEndY,newEndZ))
	
	
	OUT = wire
	
except: 
	import traceback
	errorReport = traceback.format_exc()
	OUT = errorReport
TransactionManager.Instance.TransactionTaskDone()

All help is greatly appreciated, this has been driving me crazy for the past week or so. :slight_smile:

*forgot to mention that I am a noob,

Hello @bogdan.petrescu63URX
can you post a screenshot of your Dynamo graph?

Hello @c.poupin , sure, the script in my first post is in the main graph all the way to the right.

I am trying for a single wire, the first one.

Here are the joined pics, don’t think i have the right yet to post more than 1 picture:

had to scale it, it was too big…hope it is still readable.
It is…open image in new Tab, then thenyou have to manually zoom in on it, using Ctrl+Scroll.

*also found in the script that runs the wire constructor (the one to the right most side in the second pic, the custom node) this:

verptxyz=[]
for v in verpt:
	verptxyz.append(v.ToXyz(True))

looks like a method taking a Point and converting it to a XYZ type…
tried like this too : feeding a Point and trying to convert it in the same manner to a XYZ… still not working.

Even tried to manually provide values for XYZ constructor for the start point with X changed with +1 value.

It STILL moved the vertex far away if i remember correctly (un-real).

Are you tried this?

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
#
# SOME LINES OF YOUR CODE
#
xyzStart = DS.Point.ByCoordinates(newStartX[0],newStartY[0],newStartZ[0])
wire.SetVertex(0,xyzStart.ToXyz())
#
# REST OF YOUR CODE
#
1 Like

Thank you for the suggestion!

Will give it a go in about 1h .
Fingers crossed…

YOU mister @c.poupin ARE A LIFE SAVER!!!

It works for Start and End points of wire!!! And it keeps them connected to the devices too!!!

almost went crazy with fiddling with ways of creating XYZs!!!

Thank you VERY MUCH!!!

I looked in the Revit API…where else should i look for … all these other special stuff?

For Point class i did not find the “ToXyz()” method… where’s that one? Did i miss it?

1 Like

Comeback with a failure @c.poupin …because why not?

So i try and add this piece of code into the python script which constructs the wire, after the wire is created and connected but cannot seem to get it to work.
The wire is created but the end vertices are not moved. It complains about the ToXyz method (right?)
Why would it be a problem to move the said vertices After the wire is created?..

Code is here:

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

import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

#############^^^forum solution code above

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('System')
from System.Collections.Generic import List

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)


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

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


clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB.Electrical import *
import System

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

from System.Collections.Generic import *


wiretypeid=UnwrapElement(IN[0]).Id
viewid=UnwrapElement(IN[1]).Id
wiringtype= UnwrapElement(IN[2])
verpt= UnwrapElement(IN[3])
sconn= UnwrapElement(IN[4])
econn= UnwrapElement(IN[5])
newStartX = IN[6]
newStartY = IN[7]
newStartZ = IN[8]
newEndX = IN[9]
newEndY = IN[10]
newEndZ = IN[11]

verptxyz=[]
for v in verpt:
	verptxyz.append(v.ToXyz(True))

TransactionManager.Instance.EnsureInTransaction(doc)

errorReport=[]
try:
	
	wire= Autodesk.Revit.DB.Electrical.Wire.Create(doc,wiretypeid,viewid,wiringtype,verptxyz,sconn,econn)
	
###solution from forum downwards
	xyzStart = DS.Point.ByCoordinates(newStartX[0],newStartY[0],newStartZ[0])
	wire.SetVertex(0,xyzStart.ToXyz())
	
	xyzEnd = DS.Point.ByCoordinates(newEndX[0],newEndY[0],newEndZ[0])
	lastVertexIndex = wire.NumberOfVertices - 1
	wire.SetVertex(lastVertexIndex, xyzEnd.ToXyz())
	
####
	   	
	
	OUT = wire
except: 
	import traceback
	errorReport = traceback.format_exc()
	OUT = errorReport
TransactionManager.Instance.TransactionTaskDone()

Also, having a separate custom node to move the end vertices after all wires are created does not seem to work either - actually i cannot get it to work.

For 1 single wire it works, for more…i feed the wire list, then start + end points lists of polycurves… with/without levels, tried everything, if i don’t provide levels for wires will get “list object does not have SetVertex attribute…” so need level1 on wire list…

For points if i use/ don’t use level it still does not work. - one gives error like " ‘float’ object is not subscriptable" which i found it means something like … it needs a list as input so no levels needed…

You need to read this

1 Like

Thank you, will read it.

The error indicates that your object “newStartX” is null, it’s not an iterable

I will look into it.

i am pretty sure newStartX is a List with 1 element.
as you also created a DS.Point using newStartX,Y,Z as lists and getting the first(and only) element inside…

xyzStart = DS.Point.ByCoordinates(newStartX[0],newStartY[0],newStartZ[0])

As i said, your code works fine for a single cable.
So i want to add it in the block with the constructor of the wire, and use it the same way as i did when it
is working. Except it is not. I will keep digging.

Thank you very much for your help!

If i use the python script block you provided I don’t know how to process all the wires and all the new Start and End Points without making a new Custom Node, and if I do put it in a Custom Node something just breaks. (something besides my nerves :smiley: )

I will keep trying.

1 Like

@c.poupin

Hello!!!
I got it!!!

Added your code to a custom node which takes both the Wires list and the PolyCurves from which the wires are made and moves the end vertices exactly where I want them!!!

Thank you SO MUCH!!!

And yes, ‘float’ is not iterable - it took the value directly, even though it was in a list… so i removed the [0] from the new coordinates and that was IT. :upside_down_face:

2 Likes

Hi Bogdan,

Can you share your final script?

hi @ricky.salmasan

#import clr
#clr.AddReference('ProtoGeometry')
#from Autodesk.DesignScript.Geometry import *
###
####
import sys
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
#####
####
###ce e intre comments am adaugat de la copin Cyril forum.

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference('System')
from System.Collections.Generic import List

import sys
pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)


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

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


clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB.Electrical import *
import System

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

from System.Collections.Generic import *


wire=UnwrapElement(IN[0])
newStartX = IN[1]
newStartY = IN[2]
newStartZ = IN[3]
#the above X value has 1 already added to it, then rounded
newEndX = IN[4]
newEndY = IN[5]
newEndZ = IN[6]

TransactionManager.Instance.EnsureInTransaction(doc)

errorReport=[]
try:
	
	
	#________# ASTA AR TREB SA MEARGA
	#xyzStart = Autodesk.Revit.DB.XYZ(newStartX[0],newStartY[0],newStartZ[0])
	#wire.SetVertex(0, XYZ(0,0,0))
	##wire.SetVertex(0,newStartPoint)
	
	#xyzStart = DS.Point.ByCoordinates(newStartX[0],newStartY[0],newStartZ[0])
	xyzStart = DS.Point.ByCoordinates(newStartX,newStartY,newStartZ)
	wire.SetVertex(0,xyzStart.ToXyz())
	
	#xyzEnd = DS.Point.ByCoordinates(newEndX[0],newEndY[0],newEndZ[0])
	xyzEnd = DS.Point.ByCoordinates(newEndX,newEndY,newEndZ)
	lastVertexIndex = wire.NumberOfVertices - 1
	wire.SetVertex(lastVertexIndex, xyzEnd.ToXyz())
	
	#________# ASTA AR TREB SA MEARGA
	#xyzEnd = Autodesk.Revit.DB.XYZ(newEndX[0],newEndY[0],newEndZ[0])
	##lastvertIndex = wire.NumberOfVertices - 1
	##wire.SetVertex(lastvertIndex, newEndPoint)
	#wire.SetVertex(lastvertIndex, XYZ(newEndX,newEndY,newEndZ))
	
	
	OUT = wire
	
except: 
	import traceback
	errorReport = traceback.format_exc()
	OUT = errorReport
TransactionManager.Instance.TransactionTaskDone()

i am moving the start and end wire vertices after the wire is connected to devices.

the # lines are comments, it’s a mess… but yeah. it works :slight_smile:

Thanks a lot Bogdan for your prompt reply…

I works perfectly with single wire, but when i try on 2 more wires it doesn’t work…

But still a great sharing…thanks a lot again…

check this last piece, i cannot send full picture of the script - it crashes - tried several times.

i have the list levels set to @L1.