GeometryExpressionBuilder
using Autodesk.DesignScript.Geometry.Properties;
using Autodesk.DesignScript.Interfaces;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Autodesk.DesignScript.Geometry
{
internal class GeometryExpressionBuilder
{
private static readonly string kImportMethodPrefix;
private StringBuilder mExpression = new StringBuilder();
private int id;
private static Dictionary<Type, Func<GeometryExpressionBuilder, IDesignScriptEntity, string, string>> mWriters;
static GeometryExpressionBuilder()
{
kImportMethodPrefix = "__import_";
mWriters = new Dictionary<Type, Func<GeometryExpressionBuilder, IDesignScriptEntity, string, string>>();
mWriters.Add(typeof(ICoordinateSystemEntity), GeometryExpressionBuilder.WriteEntity<ICoordinateSystemEntity>);
mWriters.Add(typeof(IPointEntity), GeometryExpressionBuilder.WriteEntity<IPointEntity>);
mWriters.Add(typeof(ILineEntity), GeometryExpressionBuilder.WriteEntity<ILineEntity>);
mWriters.Add(typeof(ICircleEntity), GeometryExpressionBuilder.WriteEntity<ICircleEntity>);
mWriters.Add(typeof(IArcEntity), GeometryExpressionBuilder.WriteEntity<IArcEntity>);
mWriters.Add(typeof(INurbsCurveEntity), GeometryExpressionBuilder.WriteEntity<INurbsCurveEntity>);
mWriters.Add(typeof(ISurfaceEntity), GeometryExpressionBuilder.WriteEntity<ISurfaceEntity>);
mWriters.Add(typeof(ISolidEntity), GeometryExpressionBuilder.WriteEntity<ISolidEntity>);
}
public static string WriteEntity<T>(GeometryExpressionBuilder eb, IDesignScriptEntity entity, string paramName) where T : IDesignScriptEntity
{
return eb.WriteEntity((object)(T)(object)entity, paramName);
}
private string WriteEntity(object p, string paramName)
{
throw new NotImplementedException();
}
public string WriteEntity(IPointEntity point, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
mExpression.AppendFormat("{0} = Point.ByCoordinates({1}, {2}, {3});", paramName, point.get_X(), point.get_Y(), point.get_Z());
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(IVectorEntity vector, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
mExpression.AppendFormat("{0} = Vector.ByCoordinates({1}, {2}, {3});", paramName, vector.get_X(), vector.get_Y(), vector.get_Z());
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(ICoordinateSystemEntity cs, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
string text = this.WriteEntity(cs.get_Origin(), (string)null);
string text2 = this.WriteEntity(cs.get_XAxis(), (string)null);
string text3 = this.WriteEntity(cs.get_YAxis(), (string)null);
string text4 = this.WriteEntity(cs.get_ZAxis(), (string)null);
mExpression.AppendFormat("{0} = CoordinateSystem.ByOriginVectors({1}, {2}, {3}, {4});", paramName, text, text2, text3, text4);
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(ILineEntity line, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
string arg = this.WriteEntity(line.get_StartPoint(), (string)null);
string arg2 = this.WriteEntity(line.get_EndPoint(), (string)null);
mExpression.AppendFormat("{0} = Line.ByStartPointEndPoint({1}, {2});", paramName, arg, arg2);
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(ICircleEntity circle, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
string text = this.WriteEntity(circle.get_CenterPoint(), (string)null);
string text2 = this.WriteEntity(circle.get_Normal(), (string)null);
mExpression.AppendFormat("{0} = Circle.ByCenterPointRadius({1}, {2}, {3});", paramName, text, circle.get_Radius(), text2);
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(IArcEntity arc, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
string text = this.WriteEntity(arc.get_CenterPoint(), (string)null);
string text2 = this.WriteEntity(arc.get_Normal(), (string)null);
mExpression.AppendFormat("{0} = Arc.ByCenterPointRadiusAngle({1}, {2}, {3}, {4}, {5});", paramName, text, arc.get_Radius(), GeometryExtension.RadiansToDegrees(arc.get_StartAngle()), GeometryExtension.RadiansToDegrees(arc.get_SweepAngle()), text2);
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(INurbsCurveEntity bspline, string paramName = null)
{
if (string.IsNullOrEmpty(paramName))
paramName = $"""{++id}";
IPointEntity[] geometry = bspline.ControlPoints();
string text = WriteEntities((IGeometryEntity[])geometry);
mExpression.AppendFormat("{0} = BSplineCurve.ByControlVertices({1}, {2}, {3});", paramName, text, bspline.get_Degree(), bspline.get_IsPeriodic());
mExpression.AppendLine();
return paramName;
}
public string WriteEntity(ISolidEntity solid, string paramName)
{
WriteSATImport((IGeometryEntity[])new IGeometryEntity[1] {
solid
}, paramName);
return paramName;
}
public string WriteEntity(ISurfaceEntity surface, string paramName)
{
WriteSATImport((IGeometryEntity[])new IGeometryEntity[1] {
surface
}, paramName);
return paramName;
}
private string WriteSATImport(IGeometryEntity[] entities, string paramName)
{
string text = $"{paramName}""{DateTime.Now}""";
string text2 = Path.Combine(Path.GetDirectoryName(GeometrySettings.RootModulePath), text);
string value = HostFactory.Factory.SaveSAT(text2, (object[])entities);
if (!text2.Equals(value, StringComparison.Ordinal))
throw new Exception(Resources.SATFileExportedException);
mExpression.AppendFormat("{0} = Geometry.ImportFromSAT(\"{1}\");", paramName, text2);
mExpression.AppendLine();
return text;
}
private string WriteDSEntity(IDesignScriptEntity entity, string paramName = null)
{
Type[] interfaces = ((object)entity).GetType().GetInterfaces();
for (int num = interfaces.Length - 1; num >= 0; num--) {
if (mWriters.TryGetValue(interfaces[num], out Func<GeometryExpressionBuilder, IDesignScriptEntity, string, string> value))
return value(this, entity, paramName);
}
throw new NotImplementedException();
}
public override string ToString()
{
return mExpression.ToString();
}
public string WriteEntities(IGeometryEntity[] geometry)
{
StringBuilder stringBuilder = new StringBuilder("{");
foreach (IGeometryEntity entity in geometry) {
try {
string arg = WriteDSEntity(entity, null);
stringBuilder.AppendFormat("{0}, ", arg);
} catch (NotImplementedException) {
}
}
StringBuilder stringBuilder2 = stringBuilder;
stringBuilder2.Remove(stringBuilder2.Length - 1, 1);
stringBuilder.Append("}");
return stringBuilder.ToString();
}
private void WriteString(string value)
{
mExpression.AppendLine(value);
}
public static string GetExpression(IGeometryEntity[] entities, string paramName)
{
GeometryExpressionBuilder geometryExpressionBuilder = new GeometryExpressionBuilder();
string text = kImportMethodPrefix + paramName;
geometryExpressionBuilder.WriteString($"""{text}""");
if (entities.Length == 1)
geometryExpressionBuilder.WriteDSEntity(entities[0], "return");
else {
List<IGeometryEntity> list = new List<IGeometryEntity>();
List<IGeometryEntity> list2 = new List<IGeometryEntity>();
foreach (IGeometryEntity val in entities) {
if (val is ISurfaceEntity || val is ISolidEntity)
list2.Add(val);
else
list.Add(val);
}
string text2 = "__sat";
if (list2.Count > 0)
geometryExpressionBuilder.WriteSATImport(list2.ToArray(), text2);
if (list.Count > 0) {
string text3 = geometryExpressionBuilder.WriteEntities(list.ToArray());
if (list2.Count > 0)
geometryExpressionBuilder.WriteString(string.Format("return = Flatten({{{1}, {0}}});", text2, text3));
else
geometryExpressionBuilder.WriteString($"""{text3}""");
}
}
geometryExpressionBuilder.WriteString("}");
geometryExpressionBuilder.WriteString($"{paramName}""{text}""");
return geometryExpressionBuilder.ToString();
}
}
}