Geometry
using Autodesk.DesignScript.Geometry.Properties;
using Autodesk.DesignScript.Interfaces;
using Autodesk.DesignScript.Runtime;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Autodesk.DesignScript.Geometry
{
public abstract class Geometry : DesignScriptEntity
{
private static Dictionary<Type, Func<IGeometryEntity, bool, Geometry>> mGeometryContructors;
private Geometry mContext;
private static Type mCachedType;
private static Func<IGeometryEntity, bool, Geometry> mCachedConstructor;
internal IPersistentObject mPersistent;
public BoundingBox BoundingBox => BoundingBox.Wrap(GeometryEntity.get_BoundingBox(), true);
public BoundingBox OrientedBoundingBox => BoundingBox.Wrap(GeometryEntity.get_OrientedBoundingBox(), true);
public CoordinateSystem ContextCoordinateSystem => CoordinateSystem.Wrap(GeometryEntity.get_ContextCoordinateSystem(), true);
internal override IDesignScriptEntity HostImpl {
get {
if (mPersistent != null)
return mPersistent.get_Geometry();
return base.HostImpl;
}
}
internal IGeometryEntity GeometryEntity => HostImpl as IGeometryEntity;
internal bool IsPersistent => mPersistent != null;
static Geometry()
{
mGeometryContructors = new Dictionary<Type, Func<IGeometryEntity, bool, Geometry>>();
Type[] types = Assembly.GetExecutingAssembly().GetTypes();
Type[] array = types;
foreach (Type type in array) {
if (type.IsClass && !type.IsAbstract && typeof(Geometry).IsAssignableFrom(type)) {
MethodInfo method = type.GetMethod("InitType", BindingFlags.Static | BindingFlags.NonPublic);
if ((MethodInfo)null != method)
method.Invoke(null, null);
}
}
}
internal static void RegisterHostType(Type hostType, Func<IGeometryEntity, bool, Geometry> contructor)
{
mGeometryContructors[hostType] = contructor;
}
internal static Geometry Wrap(IGeometryEntity host, bool persist = false, Geometry context = null)
{
if (host == null)
return null;
if (host.get_Owner() != null)
return host.get_Owner() as Geometry;
Func<IGeometryEntity, bool, Geometry> geomConstructor = GetGeomConstructor(host);
if (geomConstructor == null)
throw new InvalidOperationException(string.Format(Resources.InvalidOperationException, ((object)host).GetType()));
return geomConstructor(host, persist);
}
internal static Geometry[] Wrap(IGeometryEntity[] geometries)
{
List<Geometry> list = new List<Geometry>();
foreach (IGeometryEntity host in geometries) {
list.Add(Wrap(host, false, null));
}
return list.ToArray();
}
internal static IGeometryEntity[] Unwrap(Geometry[] geometries)
{
List<IGeometryEntity> list = new List<IGeometryEntity>();
foreach (Geometry geometry in geometries) {
list.Add(geometry.GeometryEntity);
}
return list.ToArray();
}
internal static IGeometryEntity[] Unwrap(IEnumerable<Geometry> o)
{
return (from x in o
select Unwrap(x)).ToArray();
}
internal static IGeometryEntity Unwrap(Geometry geom)
{
return geom.GeometryEntity;
}
private static Func<IGeometryEntity, bool, Geometry> GetGeomConstructor(IGeometryEntity host)
{
Type type = ((object)host).GetType();
if (type == mCachedType)
return mCachedConstructor;
Type[] interfaces = type.GetInterfaces();
interfaces = interfaces.Except(interfaces.SelectMany((Type t) => t.GetInterfaces())).ToArray();
Type[] array = interfaces;
foreach (Type key in array) {
if (mGeometryContructors.TryGetValue(key, out Func<IGeometryEntity, bool, Geometry> value)) {
mCachedType = type;
mCachedConstructor = value;
return value;
}
}
return null;
}
internal Geometry(IGeometryEntity host, bool persist)
: base(host, true)
{
InitGeometry(persist);
}
internal Geometry(Func<IGeometryEntity> constructor, bool persist)
: base((Func<IDesignScriptEntity>)constructor)
{
InitGeometry(persist);
}
[IsVisibleInDynamoLibrary(false)]
public static Geometry FromObject(long ptr)
{
IPersistentObject val = HostFactory.PersistenceManager.FromObject(ptr);
Geometry geometry = Wrap(val.get_Geometry(), false, null);
geometry.mPersistent = val;
return geometry;
}
private void InitGeometry(bool persist)
{
if (persist)
Persist();
}
internal IPersistentObject Persist()
{
if (mPersistent != null)
return mPersistent;
if ((object)HostFactory.PersistenceManager == null)
return null;
IGeometryEntity val = HostImpl as IGeometryEntity;
if (val == null)
return null;
DisposeDisplay();
mPersistent = HostFactory.PersistenceManager.Persist(val);
return mPersistent;
}
protected override void DisposeDisplayable()
{
DisposeDisplay();
if (mPersistent != null)
mPersistent.Erase();
base.DisposeDisplayable();
}
protected override void Dispose(bool disposing)
{
if (disposing) {
if (mPersistent != null && (object)mPersistent != (object)base.HostImpl)
((IDisposable)mPersistent).Dispose();
GeometryExtension.DisposeObject(ref mContext);
}
mPersistent = null;
base.Dispose(disposing);
}
private void DisposeDisplay()
{
}
internal static int GetIndexOfNearestGeometry(IGeometryEntity[] entities, IPointEntity point)
{
double num = entities[0].DistanceTo(point);
int result = 0;
for (int i = 1; i < entities.Length; i++) {
double num2 = entities[i].DistanceTo(point);
if (num2 < num) {
num = num2;
result = i;
}
}
return result;
}
public Geometry Translate(double xTranslation = 0, double yTranslation = 0, double zTranslation = 0)
{
DesignScriptEntity.CheckArgsForAsmExtents(new List<double> {
xTranslation,
yTranslation,
zTranslation
});
xTranslation /= DesignScriptEntity.scaleFactor;
yTranslation /= DesignScriptEntity.scaleFactor;
zTranslation /= DesignScriptEntity.scaleFactor;
IGeometryEntity host = GeometryEntity.Translate(xTranslation, yTranslation, zTranslation) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Translate(Vector direction)
{
IGeometryEntity host = GeometryEntity.Translate(direction.VectorEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Translate(Vector direction, double distance)
{
DesignScriptEntity.CheckArgsForAsmExtents(new List<double> {
distance
});
distance /= DesignScriptEntity.scaleFactor;
IGeometryEntity host = GeometryEntity.Translate(direction.VectorEntity, distance) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Transform(CoordinateSystem cs)
{
IGeometryEntity host = GeometryEntity.Transform(cs.CoordinateSystemEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Transform(CoordinateSystem fromCoordinateSystem, CoordinateSystem contextCoordinateSystem)
{
IGeometryEntity host = GeometryEntity.TransformFromTo(fromCoordinateSystem.CoordinateSystemEntity, contextCoordinateSystem.CoordinateSystemEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Rotate(Point origin, Vector axis, double degrees = 0)
{
IGeometryEntity host = GeometryEntity.Rotate(origin.PointEntity, axis.VectorEntity, degrees) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Rotate(Plane basePlane, double degrees = 0)
{
IGeometryEntity host = GeometryEntity.Rotate(basePlane.PlaneEntity, degrees) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Mirror(Plane mirrorPlane)
{
IGeometryEntity host = GeometryEntity.Mirror(mirrorPlane.PlaneEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Scale(double amount = 1)
{
IGeometryEntity host = GeometryEntity.Scale(amount) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Scale(double xamount = 1, double yamount = 1, double zamount = 1)
{
IGeometryEntity host = GeometryEntity.Scale(xamount, yamount, zamount) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Scale(Plane plane, double xamount = 1, double yamount = 1, double zamount = 1)
{
IGeometryEntity host = GeometryEntity.Scale(Plane.Unwrap(plane), xamount, yamount, zamount) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Scale(Point basePoint, Point from, Point to)
{
IGeometryEntity host = GeometryEntity.Scale(basePoint.PointEntity, from.PointEntity, to.PointEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Scale1D(Point basePoint, Point from, Point to)
{
IGeometryEntity host = GeometryEntity.Scale1D(basePoint.PointEntity, from.PointEntity, to.PointEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public Geometry Scale2D(Plane basePlane, Point from, Point to)
{
IGeometryEntity host = GeometryEntity.Scale2D(basePlane.PlaneEntity, from.PointEntity, to.PointEntity) as IGeometryEntity;
return Wrap(host, true, null);
}
public double DistanceTo(Geometry other)
{
return GeometryEntity.DistanceTo(other.GeometryEntity) * DesignScriptEntity.scaleFactor;
}
public Point ClosestPointTo(Geometry other)
{
IPointEntity host = GeometryEntity.ClosestPointTo(other.GeometryEntity);
return Point.Wrap(host, true);
}
public bool DoesIntersect(Geometry other)
{
return GeometryEntity.DoesIntersect(other.GeometryEntity);
}
public Geometry[] Intersect(Geometry other)
{
return Wrap(GeometryEntity.Intersect(other.GeometryEntity));
}
public Geometry[] IntersectAll(IEnumerable<Geometry> others)
{
return Wrap(GeometryEntity.IntersectAll(Unwrap(others)));
}
public Geometry[] Split(Geometry other)
{
return Wrap(GeometryEntity.Split(other.GeometryEntity));
}
public Geometry[] Trim(Geometry other, Point pick)
{
return Wrap(GeometryEntity.Trim(other.GeometryEntity, pick.PointEntity));
}
public Geometry[] Explode()
{
return Track(Wrap(GeometryEntity.Explode())).ToArray();
}
public bool IsAlmostEqualTo(Geometry other)
{
return GeometryEntity.IsAlmostEqualTo(other.GeometryEntity);
}
public string ToSolidDef()
{
return GeometryEntity.ToSolidDef();
}
[SupressImportIntoVM]
public string ToJson()
{
return GeometryEntity.ToJson(DesignScriptEntity.scaleFactor);
}
[IsVisibleInDynamoLibrary(false)]
public Geometry[] Approximate()
{
return Wrap(GeometryEntity.Approximate());
}
internal Geometry SetAttributes(Dictionary<string, string> attributes)
{
return Wrap(GeometryEntity.SetAttributes(attributes), false, null);
}
internal IDictionary<string, string> GetAttributes()
{
return GeometryEntity.GetAttributes();
}
[AllowRankReduction]
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use overload that specifies mm per unit")]
[IsObsolete("geometry_importfromsat_deprecated", typeof(Resources))]
public static Geometry[] ImportFromSAT(FileInfo file)
{
string fileName = file.FullName;
IGeometryEntity[] hosts = ImportFromSAT(ref fileName, 1000);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
[AllowRankReduction]
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use overload that specifies mm per unit")]
[IsObsolete("geometry_importfromsat_deprecated", typeof(Resources))]
public static Geometry[] ImportFromSAT(string filePath)
{
IGeometryEntity[] hosts = ImportFromSAT(ref filePath, 1000);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
[AllowRankReduction]
[IsVisibleInDynamoLibrary(false)]
public static Geometry[] ImportFromSAT(FileInfo file, double mmPerUnit)
{
string fileName = file.FullName;
IGeometryEntity[] hosts = ImportFromSAT(ref fileName, mmPerUnit);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
[AllowRankReduction]
[IsVisibleInDynamoLibrary(false)]
public static Geometry[] ImportFromSAT(string filePath, double mmPerUnit)
{
IGeometryEntity[] hosts = ImportFromSAT(ref filePath, mmPerUnit);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
internal static IGeometryEntity[] ImportFromSAT(ref string fileName, double mmPerUnit)
{
if (string.IsNullOrWhiteSpace(fileName))
throw new ArgumentNullException("fileName");
fileName = GeometryExtension.LocateFile(fileName);
if (!File.Exists(fileName))
throw new ArgumentException(string.Format(Resources.FileNotFound, fileName), "fileName");
return HostFactory.Factory.LoadSAT(fileName, DesignScriptEntity.scaleFactor, mmPerUnit);
}
[AllowRankReduction]
public static Geometry[] FromSolidDef(string solidDefJson)
{
IGeometryEntity[] hosts = FromSolidDef(ref solidDefJson);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
internal static IGeometryEntity[] FromSolidDef(ref string solidDefJson)
{
if (string.IsNullOrWhiteSpace(solidDefJson))
throw new ArgumentNullException("solidDefJson");
return HostFactory.Factory.FromSolidDef(solidDefJson);
}
[SupressImportIntoVM]
public static Geometry FromJson(string json)
{
return Wrap(HostFactory.Factory.GeometryFromJson(json, DesignScriptEntity.scaleFactor), false, null);
}
[SupressImportIntoVM]
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use ExportToSAT(IEnumerable<Geometry> geometry, string filePath) instead")]
public string ExportToSAT(string filePath)
{
List<Geometry> list = new List<Geometry>();
list.Add(this);
return ExportToSAT(list.ToArray(), filePath);
}
[SupressImportIntoVM]
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use ExportToSAT UI node instead")]
public string ExportToSAT(string filePath, double unitsMM)
{
List<Geometry> list = new List<Geometry>();
list.Add(this);
return ExportToSAT(list.ToArray(), filePath, unitsMM);
}
public static string ExportToSAT(IEnumerable<Geometry> geometry, string filePath)
{
return CheckPathAndExportToSAT(geometry, filePath, false, 0);
}
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use ExportToSAT UI node instead")]
[IsObsolete("geometry_exporttosat_deprecated", typeof(Resources))]
public static string ExportToSAT(IEnumerable<Geometry> geometry, string filePath, double unitsMM)
{
return CheckPathAndExportToSAT(geometry, filePath, true, unitsMM);
}
[IsVisibleInDynamoLibrary(false)]
public static Geometry[] FromNativePointer(IntPtr nativePointer)
{
IGeometryEntity[] hosts = HostFactory.Factory.FromNativePointer(nativePointer, DesignScriptEntity.scaleFactor);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
[IsVisibleInDynamoLibrary(false)]
public static IntPtr[] ToNativePointer(IEnumerable<Geometry> geometry)
{
List<IGeometryEntity> list = new List<IGeometryEntity>();
foreach (Geometry item in geometry) {
IGeometryEntity geometryEntity = item.GeometryEntity;
if (geometryEntity != null)
list.Add(geometryEntity);
}
object factory = (object)HostFactory.Factory;
object[] array = list.ToArray();
return factory.ToNativePointer(array, DesignScriptEntity.scaleFactor);
}
private static string CheckPathAndExportToSAT(IEnumerable<Geometry> geometry, string filePath, bool useUnits, double unitsMM = 0)
{
List<IGeometryEntity> list = new List<IGeometryEntity>();
foreach (Geometry item in geometry) {
IGeometryEntity geometryEntity = item.GeometryEntity;
if (geometryEntity != null)
list.Add(geometryEntity);
}
if (list.Count == 0)
throw new Exception(Resources.ConversionException);
if (!filePath.EndsWith(".sat"))
filePath += ".sat";
if (!Path.IsPathRooted(filePath)) {
string text = GeometrySettings.RootModulePath;
if (string.IsNullOrEmpty(text))
text = AppDomain.CurrentDomain.BaseDirectory;
string directoryName = Path.GetDirectoryName(text);
filePath = Path.Combine(directoryName, filePath);
}
object[] array;
if (!useUnits) {
object factory = (object)HostFactory.Factory;
string text2 = filePath;
array = list.ToArray();
return factory.SaveSAT(text2, array, DesignScriptEntity.scaleFactor);
}
object factory2 = (object)HostFactory.Factory;
string text3 = filePath;
array = list.ToArray();
return factory2.SaveSAT(text3, array, unitsMM, DesignScriptEntity.scaleFactor);
}
[SupressImportIntoVM]
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Use SerializeAsSAB(IEnumerable<Geometry> geometry")]
public byte[] SerializeAsSAB()
{
List<Geometry> list = new List<Geometry>();
list.Add(this);
return SerializeAsSAB(list.ToArray());
}
public static byte[] SerializeAsSAB(IEnumerable<Geometry> geometry)
{
List<IGeometryEntity> list = new List<IGeometryEntity>();
foreach (Geometry item in geometry) {
IGeometryEntity geometryEntity = item.GeometryEntity;
if (geometryEntity != null)
list.Add(geometryEntity);
}
object factory = (object)HostFactory.Factory;
object[] array = list.ToArray();
return factory.SerializeAsSAB(array, DesignScriptEntity.scaleFactor);
}
[AllowRankReduction]
[Obsolete("This method is deprecated and will be removed in a future version of Dynamo. Please use overload that allows passing mmPerUnit")]
[IsObsolete("geometry_deserializefromsab_deprecated", typeof(Resources))]
public static Geometry[] DeserializeFromSAB(byte[] buffer)
{
IGeometryEntity[] hosts = DeserializeFromSABInternal(buffer, 1000);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
[AllowRankReduction]
[IsVisibleInDynamoLibrary(false)]
public static Geometry[] DeserializeFromSAB(byte[] buffer, double mmPerUnit)
{
IGeometryEntity[] hosts = DeserializeFromSABInternal(buffer, mmPerUnit);
return hosts.ToArray<Geometry, IGeometryEntity>(true, (Geometry)null);
}
internal static IGeometryEntity[] DeserializeFromSABInternal(byte[] buffer, double mmPerUnit)
{
return HostFactory.Factory.DeserializeFromSAB(buffer, DesignScriptEntity.scaleFactor, mmPerUnit);
}
[SupressImportIntoVM]
public static void UpdateDisplay()
{
HostFactory.PersistenceManager.UpdateDisplay();
}
protected override int ComputeHashCode()
{
int num = (mPersistent != null) ? ((object)mPersistent).GetHashCode() : 0;
if (num != 0)
return num;
return base.ComputeHashCode();
}
internal static string GetFullPath(string fileName)
{
if (Path.IsPathRooted(fileName))
return fileName;
IConfiguration configuration = Application.Instance.Session as IConfiguration;
return Path.Combine(Path.GetDirectoryName(configuration.RootModulePath), fileName);
}
}
}