Files

193 lines
6.1 KiB
C#
Raw Permalink Normal View History

2026-02-23 14:58:05 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.DirectContext3D;
using Autodesk.Revit.DB.ExternalService;
namespace RevitJigSample.ExternalGraphics
{
public class DrawingServer : IDirectContext3DServer
{
private readonly Guid guid;
private RenderingPassBufferStorage edgeBufferStorage;
public DrawingServer(Document doc)
{
this.guid = Guid.NewGuid();
this.Document = doc;
}
public Document Document { get; set; }
public Guid GetServerId()
{
return this.guid;
}
public string GetVendorId()
{
return "STSO";
}
public ExternalServiceId GetServiceId()
{
return ExternalServices.BuiltInExternalServices.DirectContext3DService;
}
public virtual string GetName()
{
return "";
}
public virtual string GetDescription()
{
return "";
}
public string GetApplicationId()
{
return "";
}
public string GetSourceId()
{
return "";
}
public bool UsesHandles()
{
return false;
}
public virtual bool CanExecute(View view)
{
Document doc = view.Document;
return doc.Equals(this.Document);
}
public virtual Outline GetBoundingBox(View view)
{
return null;
}
public bool UseInTransparentPass(View view)
{
return true;
}
// Submits the geometry for rendering.
public virtual void RenderScene(View view, DisplayStyle displayStyle)
{
try
{
// Populate geometry buffers if they are not initialized or need updating.
this.CreateBufferStorageForElement(displayStyle, view);
// Conditionally submit line segment primitives.
if (
displayStyle != DisplayStyle.Shading
&& this.edgeBufferStorage.PrimitiveCount > 0
)
{
DrawContext.FlushBuffer(
this.edgeBufferStorage.VertexBuffer,
this.edgeBufferStorage.VertexBufferCount,
this.edgeBufferStorage.IndexBuffer,
this.edgeBufferStorage.IndexBufferCount,
this.edgeBufferStorage.VertexFormat,
this.edgeBufferStorage.EffectInstance,
PrimitiveType.LineList,
0,
this.edgeBufferStorage.PrimitiveCount
);
}
}
catch (Exception e)
{
//
}
}
public virtual List<Line> PrepareProfile()
{
return new List<Line>();
}
public virtual void CreateBufferStorageForElement(DisplayStyle displayStyle, View view)
{
this.edgeBufferStorage = new RenderingPassBufferStorage(displayStyle);
List<Line> lines = this.PrepareProfile();
foreach (Line edge in lines)
{
IList<XYZ> xyzs = edge.Tessellate();
this.edgeBufferStorage.VertexBufferCount += xyzs.Count;
this.edgeBufferStorage.PrimitiveCount += xyzs.Count - 1;
this.edgeBufferStorage.EdgeXYZs.Add(xyzs);
}
this.ProcessEdges(this.edgeBufferStorage);
}
private void ProcessEdges(RenderingPassBufferStorage bufferStorage)
{
List<IList<XYZ>> edges = bufferStorage.EdgeXYZs;
if (edges.Count == 0)
{
return;
}
// Edges are encoded as line segment primitives whose vertices contain only position information.
bufferStorage.FormatBits = VertexFormatBits.Position;
int edgeVertexBufferSizeInFloats =
VertexPosition.GetSizeInFloats() * bufferStorage.VertexBufferCount;
List<int> numVerticesInEdgesBefore = new List<int> { 0 };
bufferStorage.VertexBuffer = new VertexBuffer(edgeVertexBufferSizeInFloats);
bufferStorage.VertexBuffer.Map(edgeVertexBufferSizeInFloats);
{
VertexStreamPosition vertexStream =
bufferStorage.VertexBuffer.GetVertexStreamPosition();
foreach (IList<XYZ> xyzs in edges)
{
foreach (XYZ vertex in xyzs)
{
vertexStream.AddVertex(new VertexPosition(vertex));
}
numVerticesInEdgesBefore.Add(numVerticesInEdgesBefore.Last() + xyzs.Count);
}
}
bufferStorage.VertexBuffer.Unmap();
int edgeNumber = 0;
bufferStorage.IndexBufferCount =
bufferStorage.PrimitiveCount * IndexLine.GetSizeInShortInts();
int indexBufferSizeInShortInts = 1 * bufferStorage.IndexBufferCount;
bufferStorage.IndexBuffer = new IndexBuffer(indexBufferSizeInShortInts);
bufferStorage.IndexBuffer.Map(indexBufferSizeInShortInts);
{
IndexStreamLine indexStream = bufferStorage.IndexBuffer.GetIndexStreamLine();
foreach (IList<XYZ> xyzs in edges)
{
int startIndex = numVerticesInEdgesBefore[edgeNumber];
for (int i = 1; i < xyzs.Count; i++)
{
// Add two indices that define a line segment.
indexStream.AddLine(new IndexLine(startIndex + i - 1, startIndex + i));
}
edgeNumber++;
}
}
bufferStorage.IndexBuffer.Unmap();
bufferStorage.VertexFormat = new VertexFormat(bufferStorage.FormatBits);
bufferStorage.EffectInstance = new EffectInstance(bufferStorage.FormatBits);
}
}
}