the new lookup table is out…
is it possible to use this geometry representation from LookUpTable…
Does anyone know how it works … just one snippet ?
KR
Andreas
the new lookup table is out…
is it possible to use this geometry representation from LookUpTable…
Does anyone know how it works … just one snippet ?
KR
Andreas
I can’t give a snippet, but a few pages removed from the link you provided is this page, which I believe is the full source: RevitLookup/source/RevitLookup/Core/Visualization at dev · jeremytammik/RevitLookup · GitHub
Context? Which file is that in the repository section I sent?
Note that this is NOT an easy implementation.
i looked just in one, but here i zipped all
Geometry.7z (87.6 KB)
Your IDE or Git process is likely part of the problem. Look at one of the .cs files the github page which I linked using your browser.
OK, but from that point, how can i combine that with Revit API. So the lookup-Table is accessing Revit itself, can i based on that… create geometry via python (like chatGPT is “cheating” me)
import clr
import System
from System import Guid
from System.Collections.Generic import List
from Autodesk.Revit.DB import Solid, View, DisplayStyle, Outline, BoundingBoxXYZ
from Autodesk.Revit.DB.ExternalService import ExternalServiceRegistry, ExternalServices
from Autodesk.Revit.DB.DirectContext3D import IDirectContext3DServer, DrawContext, RenderingBufferStorage
from Autodesk.Revit.UI import UIApplication
class SolidVisualizationServer(IDirectContext3DServer):
def __init__(self):
self._solid = None
self._has_effects_updates = True
self._has_geometry_updates = True
self._guid = Guid.NewGuid()
self._render_lock = System.Object()
self._face_buffers = List[RenderingBufferStorage]()
self._edge_buffers = List[RenderingBufferStorage]()
self._transparency = 0.0
self._scale = 1.0
self._face_color = None
self._edge_color = None
self._draw_face = False
self._draw_edge = False
def GetServerId(self):
return self._guid
def GetVendorId(self):
return "RevitLookup"
def GetName(self):
return "Solid visualization server"
def GetDescription(self):
return "Solid geometry visualization"
def GetServiceId(self):
return ExternalServices.BuiltInExternalServices.DirectContext3DService
def GetApplicationId(self):
return ""
def GetSourceId(self):
return ""
def UsesHandles(self):
return False
def CanExecute(self, view):
return True
def UseInTransparentPass(self, view):
return self._draw_face and self._transparency > 0
def GetBoundingBox(self, view):
bounding_box = self._solid.GetBoundingBox()
min_point = bounding_box.Transform.OfPoint(bounding_box.Min)
max_point = bounding_box.Transform.OfPoint(bounding_box.Max)
return Outline(min_point, max_point)
def RenderScene(self, view, display_style):
with self._render_lock:
try:
if self._has_geometry_updates:
self._map_geometry_buffer()
self._has_geometry_updates = False
if self._has_effects_updates:
self._update_effects()
self._has_effects_updates = False
if self._draw_face:
is_transparent_pass = DrawContext.IsTransparentPass()
if (is_transparent_pass and self._transparency > 0) or (not is_transparent_pass and self._transparency == 0):
for buffer in self._face_buffers:
DrawContext.FlushBuffer(buffer.VertexBuffer,
buffer.VertexBufferCount,
buffer.IndexBuffer,
buffer.IndexBufferCount,
buffer.VertexFormat,
buffer.EffectInstance, PrimitiveType.TriangleList, 0,
buffer.PrimitiveCount)
if self._draw_edge:
for buffer in self._edge_buffers:
DrawContext.FlushBuffer(buffer.VertexBuffer,
buffer.VertexBufferCount,
buffer.IndexBuffer,
buffer.IndexBufferCount,
buffer.VertexFormat,
buffer.EffectInstance, PrimitiveType.LineList, 0,
buffer.PrimitiveCount)
except Exception as e:
self.RenderFailed(self, e)
def _map_geometry_buffer(self):
scaled_solid = RenderGeometryHelper.ScaleSolid(self._solid, self._scale)
face_index = 0
for face in scaled_solid.Faces:
buffer = self._create_or_update_buffer(self._face_buffers, face_index)
self._map_face_buffers(buffer, face)
face_index += 1
edge_index = 0
for edge in scaled_solid.Edges:
buffer = self._create_or_update_buffer(self._edge_buffers, edge_index)
self._map_edge_buffers(buffer, edge)
edge_index += 1
def _map_face_buffers(self, buffer, face):
mesh = face.Triangulate()
RenderHelper.MapSurfaceBuffer(buffer, mesh, 0)
def _map_edge_buffers(self, buffer, edge):
mesh = edge.Tessellate()
RenderHelper.MapCurveBuffer(buffer, mesh)
def _create_or_update_buffer(self, buffers, index):
if len(buffers) > index:
return buffers[index]
else:
buffer = RenderingBufferStorage()
buffers.Add(buffer)
return buffer
def _update_effects(self):
for buffer in self._face_buffers:
if not buffer.EffectInstance:
buffer.EffectInstance = EffectInstance(buffer.FormatBits)
buffer.EffectInstance.SetColor(self._face_color)
buffer.EffectInstance.SetTransparency(self._transparency)
for buffer in self._edge_buffers:
if not buffer.EffectInstance:
buffer.EffectInstance = EffectInstance(buffer.FormatBits)
buffer.EffectInstance.SetColor(self._edge_color)
def UpdateFaceColor(self, color):
ui_document = UIApplication.ActiveUIDocument
if ui_document is None:
return
with self._render_lock:
self._face_color = color
self._has_effects_updates = True
ui_document.UpdateAllOpenViews()
def UpdateEdgeColor(self, color):
ui_document = UIApplication.ActiveUIDocument
if ui_document is None:
return
with self._render_lock:
self._edge_color = color
self._has_effects_updates = True
ui_document.UpdateAllOpenViews()
def UpdateTransparency(self, value):
ui_document = UIApplication.ActiveUIDocument
if ui_document is None:
return
with self._render_lock:
self._transparency = value
self._has_effects_updates = True
ui_document.UpdateAllOpenViews()
def UpdateScale(self, value):
ui_document = UIApplication.ActiveUIDocument
if ui_document is None:
return
self._scale = value
with self._render_lock:
self._has_geometry_updates = True
self._has_effects_updates = True
self._face_buffers.Clear()
self._edge_buffers.Clear()
ui_document.UpdateAllOpenViews()
def UpdateFaceVisibility(self, value):
ui_document = UIApplication.ActiveUIDocument
if ui_document is None:
return
with self._render_lock:
self._draw_face = value
ui_document.UpdateAllOpenViews()
def UpdateEdgeVisibility(self, value):
ui_document = UIApplication.ActiveUIDocument
if ui_document is None:
return
with self._render_lock:
self._draw_edge = value
ui_document.UpdateAllOpenViews()
def Register(self, solid):
self._solid = solid
Application.ActionEventHandler.Raise(lambda application: self._register_internal(application))
def _register_internal(self, application):
if application.ActiveUIDocument is None:
return
direct_context_service = ExternalServiceRegistry.GetService(ExternalServices.BuiltInExternalServices.DirectContext3DService)
server_ids = direct_context_service.GetActiveServerIds()
direct_context_service.AddServer(self)
server_ids.Add(self.GetServerId())
direct_context_service.SetActiveServers(server_ids)
application.ActiveUIDocument.UpdateAllOpenViews()
def Unregister(self):
Application.ActionEventHandler.Raise(lambda application: self._unregister_internal(application))
def _unregister_internal(self, application):
direct_context_service = ExternalServiceRegistry.GetService(ExternalServices.BuiltInExternalServices.DirectContext3DService)
direct_context_service.RemoveServer(self.GetServerId())
if application.ActiveUIDocument:
application.ActiveUIDocument.UpdateAllOpenViews()
def RenderFailed(self, sender, args):
print(f"Render failed: {args.Exception}")
# Usage example:
# solid_visualization_server = SolidVisualizationServer()
# solid_visualization_server.Register(some_solid_instance)
Yes you can, but I am curious to know the ‘why’ behind this. What is your end goal? Personally Inwouldnt try to recreate via Python as it won’t be as stable or functional as what you’d get with C# due to the nature of the graphics server services.
the goal is to create geometry with this. because dynamo geometry is unstable. Sometimes revit collabses… at least i have in everrage 800MB project. Aim when it works, i will migrate to PyRevit.
No it isn’t. It’s actually orders of magnitude more stable and capable than Revit’s geometry engine. Dynamo uses the same engine as AutoCAD and many other core Autodesk tools - Revit is the outlier actually. This means that the geometry engine for Dynamo geometry has a LOT more users than that for Revit who are building stuff much more complex than what is done in Revit. As an example remember the minimum curve length and maximum geometry size - AutoCAD doesn’t have that - you can draw a microchip on the moon at scale if you wanted to.
The issues we see with geometry is usually in the translation from Revit geometry to Dynamo and vice versa - similar to how geometry imports work today - sometimes those SAT imports just aren’t right… Hopefully that clarifies things enough that we can move past knocking the Dynamo geometry engine now and get to what you are after.
Knowing that is your goal, and you’ll need to look into other tools rather than this one as this is for viewing geometry rather than the elements (what Revit typically displays). It currently does so by extracting existing geometry.
To create geometry you need to use the correct class in the Revit API, and this class will vary depending on what type of geometry you want to make. This is a partial listing:
I believe that you’re familiar with the basic curve creation methods already, but if not start there. For the higher level complexities look into the shape builder as a starting point.
Some notes before you progress:
Hi,
If it’s just for visualization, as an alternative to DirectContext3D
, you can use WPF with the HelixToolkit
library (OOTB with Dynamo)
here I’m also using the Dynamo MeshToolKit
package to simplify conversion
code (Revit 2025 + IronPython3 with WPF)
import clr
import sys
import System
clr.AddReference("System.Numerics")
clr.AddReference('HelixToolkit')
clr.AddReference('SharpDX.Mathematics')
clr.AddReference('HelixToolkit.Core.Wpf')
clr.AddReference('HelixToolkit.SharpDX.Core')
clr.AddReference('HelixToolkit.SharpDX.Core.Wpf')
from HelixToolkit import *
from HelixToolkit.Wpf.SharpDX import *
from HelixToolkit.SharpDX.Core import *
from SharpDX import *
import SharpDX
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)
clr.AddReference("IronPython.Wpf")
clr.AddReference('System.Core')
clr.AddReference('System.Xml')
clr.AddReference('PresentationCore')
clr.AddReference('PresentationFramework')
clr.AddReferenceByPartialName("WindowsBase")
from System.IO import StringReader
from System.Windows.Markup import XamlReader, XamlWriter
from System.Windows import Window, Application
try:
import wpf
import time
except ImportError:
wpf = None
class MeshViewer(Window):
LAYOUT = '''
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:hx="http://helix-toolkit.org/wpf"
Title="..."
Height="700"
Width="600">
<Grid>
<Viewbox Grid.Row="0">
<hx:HelixViewport3D
Height="400"
Width="400"
VerticalAlignment="Bottom"
ZoomExtentsWhenLoaded="True"
CameraRotationMode="Trackball"
IsViewCubeEdgeClicksEnabled="True"
ZoomAroundMouseDownPoint="True"
Margin="5,35,5,2">
<hx:DefaultLights/>
<ModelVisual3D>
<ModelVisual3D.Content>
<GeometryModel3D x:Name="model3D">
<GeometryModel3D.Geometry >
<MeshGeometry3D x:Name="meshMain">
</MeshGeometry3D>
</GeometryModel3D.Geometry>
<GeometryModel3D.Material>
<DiffuseMaterial x:Name="matDiffuseMain">
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Gray"/>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
</GeometryModel3D>
</ModelVisual3D.Content>
</ModelVisual3D>
<hx:GridLinesVisual3D Width="8" Length="8" MinorDistance="1" MajorDistance="1" Thickness="0.01"/>
</hx:HelixViewport3D >
</Viewbox>
</Grid>
</Window>
'''
def __init__(self, mesh):
self.ui = wpf.LoadComponent(self, StringReader(MeshViewer.LAYOUT))
self.mesh = mesh
self.Title = "3D Viewer"
indices = System.Windows.Media.Int32Collection([System.Int32(i) for i in mesh.VertexIndicesByTri()])
positions = System.Windows.Media.Media3D.Point3DCollection([System.Windows.Media.Media3D.Point3D(p.X, p.Y, p.Z) for p in mesh.Vertices()])
self.meshMain.TriangleIndices = indices
self.meshMain.Positions = positions
if wpf is not None:
input_mesh = IN[0]
mesh_viewer = MeshViewer(input_mesh)
mesh_viewer.Show()
thank you for pushing the topic… so it is realy a alternative for directShape.
@c.poupin can confirm, but I don’t see it generating any elements in the Revit model; it is displaying the content in this case.
If the goal is to make new model elements from existing geometry without using a direct shape you can quarry them, and generate a new family with the relevant geometry included, and then load an instance of that family.
an alternative to DirectContext3D API (not DirectShape)
you can find information about DirectContext3D API here (which is used here in RevitLookUp to visualize geometries.)
i installed meshToolkid, Ironpython2 and 3… is there still something missing
Py3DShape.dyn (15.4 KB)
@Draxl_Andreas Select the good python engine ? And you use which version of Dynamo ?