UV coordinates as double

Dear members,
I’ve been having a problem with NewRoom() and NewArea() methods, although I’m being able to find the location points from a surface in Dynamo, and I’m converting the point to a Revit XYZ, selecting the X and the Y coordinate to create a new UV(x, y) coordinate doesn`t work because it says it is called with a <class ‘float’> and not as stated in the constructor with UV(double, double). this is my code:

# Load the Python Standard and DesignScript Libraries
import clr
import struct
import cmath

clr.AddReference('RevitAPI')
#from Autodesk.Revit.DB.Visual
from Autodesk.Revit.DB import *
import Autodesk
from Autodesk.Revit.DB.Architecture import*
from Autodesk.Revit.DB.Structure import *

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

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

clr.AddReference('RevitNodes')
import Revit
#from Autodesk.Revit.Utility
clr.ImportExtensions(Revit.GeometryConversion)
clr.ImportExtensions(Revit.Elements)

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

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

doc = DocumentManager.Instance.CurrentDBDocument
uidoc=DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument

# The inputs to this node will be stored as a list in the IN variables.
phase = UnwrapElement(IN[0])
surf = UnwrapElement(IN[1])
level = UnwrapElement(IN[2])
room = UnwrapElement(IN[3])
boundingBoxes = UnwrapElement(IN[4])

out = []
uvs = []

# Place your code below this line
loc = room.Location.Point
out.append(type(loc))
out.append(loc.X)
out.append(loc.Y)
#uvRevit = UV(loc.X, loc.Y)

TransactionManager.Instance.EnsureInTransaction(doc)
#newRoom = doc.Create.NewRoom(phase)

for i in range(len(surf)):
    bb = surf[i].get_BoundingBox()
    #bbDyn = ByGeometry(surf[i])
    bbRevit = bb.ToRevitType()
    max = bbRevit.Max
    min = bbRevit.Min
    #bounds = bbRevit.Bounds
    pt = Surface.PointAtParameter(surf[i], 0.5, 0.5) #point in dynamo
    uv = Surface.UVParameterAtPoint(surf[i], pt) #uv in dynamo
    out.append(max)
    out.append(min)
    xyz = pt.ToRevitType() #convert to XYZ in Revit
    out.append(xyz)
    out.append(type(xyz.X))
    uvRevit = UV(xyz.X, xyz.Y)
	newRoom = doc.Create.NewRoom(level, uv)
	out.append(newRoom)

TransactionManager.Instance.TransactionTaskDone()

# Assign your output to the OUT variable.
OUT = out

I’ll appreciate very much your help,

Paula

UV’s are in this case just a 2D point in space, so you don’t need to use parameters to obtain them if you’re using a bounding box. If you ever do want to work that way, you would use the Evaluate method on the underlying face of the geometry/surface you are working with.

In this case we can just get the centroid of the bounding box at its top using some simple maths and generate the rooms at the resultant 2D coordinates:

# Boilerplate text
import clr

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

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

# Current doc/app/ui
doc = DocumentManager.Instance.CurrentDBDocument

# Define list/unwrap list functions
def uwlist(input):
    result = input if isinstance(input, list) else [input]
    return UnwrapElement(result)

# Preparing input from dynamo to revit
elements = uwlist(IN[0])
level = UnwrapElement(IN[1])
newRooms = []

# Function to return centroid of min max
def centroid(bb, top = False):
	# Min and max
	bbMax = bb.Max
	bbMin = bb.Min
	# Get coordinates
	cenX = (bbMax.X + bbMin.X)/2
	cenY = (bbMax.Y + bbMin.Y)/2
	if top:
		cenZ = bbMax.X
	else:
		cenZ = (bbmax.Z + bbMin.Z)/2
	# Return the point
	return XYZ(cenX, cenY, cenZ)

# Get the UV's per point, and create room at them
TransactionManager.Instance.EnsureInTransaction(doc)

for e in elements:
	# Get bb and top point
	bb = e.get_BoundingBox(None)
	bbCen = centroid(bb, top = True)
	# To UV
	uv = UV(bbCen.X, bbCen.Y)
	# Create room
	newRoom = doc.Create.NewRoom(level, uv)
	newRooms.append(newRoom)

TransactionManager.Instance.TransactionTaskDone()

# Preparing output to Dynamo
OUT = newRooms

Rooms at bounding box centroid.dyn (6.8 KB)

Hi @paulaem and welcome !

which version of Revit are you using ?

Gavin, thank you very much for the advise, I have problems with your elements regarding the definition of the enclosed area for a room if I have a set of lines, how would you do it, thank you very much again

Paula EM

In that case the rooms would somehow need to belong together - although your code doesn’t seem to be working that way, you already have a surface. From there you could join and patch them to a surface and finally bound that geometry instead and use my method, or you could evaluate the surface using that method I listed instead if you can create a face from the lines.