Select point on face one by one with previsualization

Hello everyone,

I have to select several points from a surface in Revit, and then create a geometry from them.
I’m using the springs node SelectFaces+, but I have to pick all of them at once without preview of the ones that I have just picked.
Is there any way to visualize the point before selecting the next one? It is really hard to select each one without the reference from the previous one.

Thanks, Álvaro

Here is a workaround.
draw temporary model lines that makes points as intersects with faces, and use Intersect node after select all of them at once.(of course u have to separate lines and surface)

Hello,
Here is a workaround using transient geometry and Analysis namespace (Analysis Visualization),

previewSelectPt_on_Faces


import clr
import sys
import math
import System
from System.Collections.Generic import List

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

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

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

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

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
pf_path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ProgramFilesX86)
sys.path.append(pf_path + '\\IronPython 2.7\\Lib')
	
def decoCreateAvfDisplayStyle2(func):
	def wrapper(*args, **kwargs):
		view = args[0]
		tg = TransactionGroup(doc, func.__name__)
		tg.Start()
		filterP = System.Predicate[System.Object](lambda x : x.Name == "Paint_Preview")
		analysisDisplayStyle = List[Element](FilteredElementCollector(doc).OfClass(AnalysisDisplayStyle).ToElements()).Find(filterP)
		if view.AnalysisDisplayStyleId == ElementId.InvalidElementId or analysisDisplayStyle is None :
			t = Transaction(doc, "Paint_Preview")
			t.Start()
			coloredSurfaceSettings = AnalysisDisplayColoredSurfaceSettings()
			coloredSurfaceSettings.ShowGridLines = False
			colorSettings = AnalysisDisplayColorSettings()
			legendSettings = AnalysisDisplayLegendSettings()
			legendSettings.ShowLegend = False
			analysisDisplayStyle = AnalysisDisplayStyle.CreateAnalysisDisplayStyle( doc, "Paint_Preview", coloredSurfaceSettings, colorSettings, legendSettings )
			view.AnalysisDisplayStyleId  = analysisDisplayStyle.Id
			t.Commit()
		# function Wrapp
		ret = func(*args, **kwargs) 
		tg.RollBack()            
		tg.Dispose()	
		return ret      
	return wrapper         


def createSphere(center):
	radius = 0.15 # decimal feet
	frame = Frame(center, XYZ.BasisX, XYZ.BasisY, XYZ.BasisZ)
	arc = Arc.Create(  center - radius * XYZ.BasisZ, center + radius * XYZ.BasisZ, center + radius * XYZ.BasisX )
	line = Line.CreateBound(arc.GetEndPoint( 1 ), arc.GetEndPoint( 0 ) )  
	halfCircle = CurveLoop()
	halfCircle.Append( arc )
	halfCircle.Append( line )
	sphere = GeometryCreationUtilities.CreateRevolvedGeometry(frame, List[CurveLoop]([halfCircle ]) , 0, 2 * math.pi)
	return sphere

@decoCreateAvfDisplayStyle2
def surfaceSelection(view):
	"""Pick points on the face with preview with AVF"""
	sfm = SpatialFieldManager.GetSpatialFieldManager(doc.ActiveView) 
	if sfm is None:
		sfm = SpatialFieldManager.CreateSpatialFieldManager(doc.ActiveView, 1)		
	sfm.Clear() 
	resultSchema = AnalysisResultSchema("Schema Name" , "Preview_Selection")
	schemaIndex = sfm.RegisterResult(resultSchema)
	
	outSurf = []
	flag = True
	error = None
	outgpoints = []
	TaskDialog.Show("Selection", "Select points on face, tap Esc to Finish")
	while flag:
		try:
			reference = uidoc.Selection.PickObject(ObjectType.Face, "Select points on face, tap Esc to Finish")
			selectface = doc.GetElement(reference).GetGeometryObjectFromReference(reference)
			outgpoints.append(reference.GlobalPoint.ToPoint() )
			outSurf.extend(selectface.ToProtoType())
			sphere = createSphere(reference.GlobalPoint)
			for face in sphere.Faces:
				idx = sfm.AddSpatialFieldPrimitive(face, Transform.Identity)
				uvPts = List[UV]()
				bb = face.GetBoundingBox()
				uvPts.Add(bb.Min)
				pnts = FieldDomainPointsByUV(uvPts)
				#   
				doubleList = List[System.Double]([10.0])
				vals = FieldValues(List[ValueAtPoint]([ValueAtPoint(doubleList)]))
				sfm.UpdateSpatialFieldPrimitive(idx, pnts, vals, schemaIndex)
		except :
			import traceback
			error = traceback.format_exc()
			flag = False
			break
	sfm.Clear() 
	return outSurf, outgpoints, error
	
view = doc.ActiveView
outSurf, gpoints, error = surfaceSelection(view)
OUT = outSurf, gpoints

*Note: *
currently, this code is not compatible with CPython Engine due to a bug with math Operator overloads in PythonNet (seems to be corrected on the next version of the PythonNet package)

4 Likes

Thanks so much, this is exactly what I was looking!

1 Like