Files
ViewDesignEngine/dotnet/VdeSharp/BrepModel.cs
T
茂之钳 5e2812a6f3
CI / Build & Test (push) Failing after 33s
CI / Release Build (push) Failing after 35s
Build & Test / build-and-test (push) Has been cancelled
Build & Test / python-bindings (push) Has been cancelled
feat(v6.2): Blender addon + .NET/C# bindings + developer docs + plugin system
v6.2.1 — Blender Integration Addon:
- 5 files, 1,732 lines: __init__, operators (9 ops), panels (4 panels)
- preferences, vde_bridge (subprocess CLI bridge)
- Import/Export STEP, primitives, boolean, SDF→Mesh

v6.2.2 — .NET/C# Bindings (VdeSharp):
- 8 files: NativeMethods (50+ P/Invoke), BrepModel, MeshData, SdfEngine, Assembly
- C API extended with 20 new functions (STEP I/O, Boolean, SDF, Assembly)
- vde_capi rebuilt as SHARED library
- Example: import STEP → boolean → export

v6.2.3 — Developer Docs + Plugin System:
- 7 docs: architecture, contributing, API overview, building, testing, plugin-system
- plugin_system.h/.cpp: PluginInterface, PluginManager, dlopen/LoadLibrary
- README.md updated with v6 features
- Syntax-check passed (GCC 10.2.1, -Wall -Wextra -Wpedantic)
2026-07-26 22:24:40 +08:00

192 lines
6.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Runtime.InteropServices;
namespace VdeSharp;
/// <summary>
/// Managed wrapper around a native VDE B-Rep model (VdeBodyHandle).
/// Provides STEP/IGES import/export, Boolean operations, and mesh tessellation.
/// </summary>
public class BrepModel : IDisposable
{
/// <summary>Native engine context handle</summary>
private readonly nint _ctx;
/// <summary>Native B-Rep body handle</summary>
internal nint _handle;
private bool _disposed;
/// <summary>Returns the native handle (for internal use).</summary>
internal nint Handle => _handle;
/// <summary>
/// Wraps an existing native body handle. Used internally by factory methods.
/// </summary>
internal BrepModel(nint ctx, nint handle)
{
_ctx = ctx;
_handle = handle;
}
/// <summary>
/// Creates a box primitive.
/// </summary>
public static BrepModel CreateBox(nint ctx, double w, double h, double d)
{
nint hdl = NativeMethods.vde_body_create_box(ctx, w, h, d);
return new BrepModel(ctx, hdl);
}
/// <summary>
/// Creates a cylinder primitive.
/// </summary>
public static BrepModel CreateCylinder(nint ctx, double radius, double height, int segments = 32)
{
nint hdl = NativeMethods.vde_body_create_cylinder(ctx, radius, height, segments);
return new BrepModel(ctx, hdl);
}
/// <summary>
/// Creates a sphere primitive.
/// </summary>
public static BrepModel CreateSphere(nint ctx, double radius, int su = 32, int sv = 32)
{
nint hdl = NativeMethods.vde_body_create_sphere(ctx, radius, su, sv);
return new BrepModel(ctx, hdl);
}
/// <summary>
/// Imports B-Rep models from a STEP file.
/// Returns an array of BrepModel instances.
/// </summary>
public static unsafe BrepModel[] LoadStep(nint ctx, string path)
{
nint* bodiesPtr;
int count = NativeMethods.vde_body_load_step(ctx, path, &bodiesPtr);
if (count <= 0) return Array.Empty<BrepModel>();
var result = new BrepModel[count];
for (int i = 0; i < count; i++)
result[i] = new BrepModel(ctx, bodiesPtr[i]);
// Free the pointer array (but NOT the individual handles)
Marshal.FreeHGlobal((nint)bodiesPtr);
return result;
}
/// <summary>
/// Imports B-Rep models from an IGES file.
/// </summary>
public static unsafe BrepModel[] LoadIges(nint ctx, string path)
{
nint* bodiesPtr;
int count = NativeMethods.vde_body_load_iges(ctx, path, &bodiesPtr);
if (count <= 0) return Array.Empty<BrepModel>();
var result = new BrepModel[count];
for (int i = 0; i < count; i++)
result[i] = new BrepModel(ctx, bodiesPtr[i]);
Marshal.FreeHGlobal((nint)bodiesPtr);
return result;
}
/// <summary>
/// Exports a list of BrepModel instances to a STEP file.
/// </summary>
public static void SaveStep(nint ctx, BrepModel[] bodies, string path)
{
var handles = new nint[bodies.Length];
for (int i = 0; i < bodies.Length; i++)
handles[i] = bodies[i]._handle;
NativeMethods.vde_body_save_step(ctx, handles, handles.Length, path);
}
/// <summary>
/// Exports a list of BrepModel instances to an IGES file.
/// </summary>
public static void SaveIges(nint ctx, BrepModel[] bodies, string path)
{
var handles = new nint[bodies.Length];
for (int i = 0; i < bodies.Length; i++)
handles[i] = bodies[i]._handle;
NativeMethods.vde_body_save_iges(ctx, handles, handles.Length, path);
}
/// <summary>
/// Saves this single body to a STEP file.
/// </summary>
public void SaveStep(string path)
=> SaveStep(_ctx, new[] { this }, path);
/// <summary>
/// Saves this single body to an IGES file.
/// </summary>
public void SaveIges(string path)
=> SaveIges(_ctx, new[] { this }, path);
// ═══════════════════════════════════════════════════
// Boolean operations
// ═══════════════════════════════════════════════════
/// <summary>Boolean union: this other</summary>
public BrepModel Union(BrepModel other)
{
nint hdl = NativeMethods.vde_body_boolean(_ctx, _handle, other._handle, 0);
return new BrepModel(_ctx, hdl);
}
/// <summary>Boolean intersection: this ∩ other</summary>
public BrepModel Intersect(BrepModel other)
{
nint hdl = NativeMethods.vde_body_boolean(_ctx, _handle, other._handle, 1);
return new BrepModel(_ctx, hdl);
}
/// <summary>Boolean difference: this \ other</summary>
public BrepModel Diff(BrepModel other)
{
nint hdl = NativeMethods.vde_body_boolean(_ctx, _handle, other._handle, 2);
return new BrepModel(_ctx, hdl);
}
// ═══════════════════════════════════════════════════
// Tessellation / Mesh
// ═══════════════════════════════════════════════════
/// <summary>
/// Tessellates the B-Rep model into a triangle mesh.
/// </summary>
/// <param name="deflection">Chord height error for tessellation (default 0.01)</param>
public MeshData ToMesh(double deflection = 0.01)
{
nint mh = NativeMethods.vde_body_to_mesh(_ctx, _handle, deflection);
var mesh = new MeshData(mh, ownsHandle: true);
mesh.ExtractFromNative();
return mesh;
}
/// <summary>
/// Deep clone of this B-Rep model.
/// </summary>
public BrepModel Clone()
{
nint hdl = NativeMethods.vde_body_clone(_ctx, _handle);
return new BrepModel(_ctx, hdl);
}
// ═══════════════════════════════════════════════════
// IDisposable
// ═══════════════════════════════════════════════════
public void Dispose()
{
if (!_disposed && _handle != nint.Zero)
{
NativeMethods.vde_body_free(_handle);
_handle = nint.Zero;
_disposed = true;
}
}
}