Newer
Older
using System;
using System.Collections.Generic;
MaZiFAU
committed
using static SOMDocManager;
using static CommunicationEvents;
Marco Zimmer
committed
using JsonSubTypes;
public class ParsingDictionary
{
//TODO? get rid of this, use reflection? instead, if possible
//TODO: docu
//public static Dictionary<string, Func<Scroll.ScrollFact, Fact>> parseFactDictionary = new Dictionary<string, Func<Scroll.ScrollFact, Fact>>() {
public static Dictionary<string, Func<Scroll.ScrollFact, Fact>> parseFactDictionary = new() {
MaZiFAU
committed
{SOMDocManager.MMT_OMS_URI.Point, PointFact.parseFact},
{SOMDocManager.MMT_OMS_URI.Metric, LineFact.parseFact},
{SOMDocManager.MMT_OMS_URI.Angle, AngleFact.parseFact},
{SOMDocManager.MMT_OMS_URI.LineType, RayFact.parseFact},
{SOMDocManager.MMT_OMS_URI.LineOf, RayFact.parseFact},
{SOMDocManager.MMT_OMS_URI.OnLine, OnLineFact.parseFact},
MaZiFAU
committed
{SOMDocManager.MMT_OMS_URI.Eq, AngleFact.parseFact},
MaZiFAU
committed
{SOMDocManager.MMT_OMS_URI.ParallelLine, ParallelLineFact.parseFact},
MaZiFAU
committed
{SOMDocManager.MMT_OMS_URI.CircleType3d, CircleFact.parseFact},
{SOMDocManager.MMT_OMS_URI.OnCircle, OnCircleFact.parseFact },
{SOMDocManager.MMT_OMS_URI.AnglePlaneLine, AngleCircleLineFact.parseFact },
{SOMDocManager.MMT_OMS_URI.RadiusCircleMetric, RadiusFact.parseFact },
{SOMDocManager.MMT_OMS_URI.AreaCircle, AreaCircleFact.parseFact },
{SOMDocManager.MMT_OMS_URI.OrthoCircleLine, OrthogonalCircleLineFact.parseFact },
{SOMDocManager.MMT_OMS_URI.VolumeCone, ConeVolumeFact.parseFact },
MaZiFAU
committed
{SOMDocManager.MMT_OMS_URI.TruncatedVolumeCone ,TruncatedConeVolumeFact.parseFact },
{SOMDocManager.MMT_OMS_URI.RightAngle, RightAngleFact.parseFact },
{SOMDocManager.MMT_OMS_URI.CylinderVolume, CylinderVolumeFact.parseFact },
{SOMDocManager.MMT_OMS_URI.TestType, TestFact.parseFact },
{SOMDocManager.MMT_OMS_URI.EqualityCircles, EqualCirclesFact.parseFact },
{SOMDocManager.MMT_OMS_URI.UnEqualityCircles, UnEqualCirclesFact.parseFact }
// TODO: get rid of this
public static Dictionary<string, string> parseTermsToId = new();
/// <summary>
/// class to Read AddFact Responses.
/// </summary>
// TODO: docu
public class AddFactResponse
{
public string uri;
Marco Zimmer
committed
public static bool sendAdd(MMTDeclaration mmtDecl, out string uri)
{
string body = MMTSymbolDeclaration.ToJson(mmtDecl);
return sendAdd(CommunicationEvents.ServerAdress + "/fact/add", body, out uri);
}
public static bool sendAdd(string path, string body, out string uri)
{
if (!CommunicationEvents.ServerRunning)
{
Debug.LogWarning("Server not running");
Marco Zimmer
committed
uri = null;
return false;
Marco Zimmer
committed
Marco Zimmer
committed
Debug.Log("Sending to Server:\n" + body);
//Put constructor parses stringbody to byteArray internally (goofy workaround)
Marco Zimmer
committed
using UnityWebRequest www = UnityWebRequest.Put(path, body);
www.method = UnityWebRequest.kHttpVerbPOST;
www.SetRequestHeader("Content-Type", "application/json");
www.timeout = 1;
//TODO: implement real asynchronous communication ...
AsyncOperation op = www.SendWebRequest();
while (!op.isDone) ;
if (www.result == UnityWebRequest.Result.ConnectionError
|| www.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogWarning(www.error);
Marco Zimmer
committed
uri = null;
return false;
}
else
{
string answer = www.downloadHandler.text;
Marco Zimmer
committed
AddFactResponse res = JsonUtility.FromJson<AddFactResponse>(answer);
if (VerboseURI)
Debug.Log("Server added Fact:\n" + res.uri);
uri = res.uri;
return true;
}
}
}
/// <summary>
/// %Fact representation of Unity; mostly mirrors Facts of MMT.
/// </summary>
Marco Zimmer
committed
[JsonConverter(typeof(JsonSubtypes), "s_type")]
[JsonSubtypes.KnownSubType(typeof(PointFact), nameof(PointFact))]
[JsonSubtypes.KnownSubType(typeof(LineFact), nameof(LineFact))]
[JsonSubtypes.KnownSubType(typeof(RayFact), nameof(RayFact))]
[JsonSubtypes.KnownSubType(typeof(OnLineFact), nameof(OnLineFact))]
[JsonSubtypes.KnownSubType(typeof(AngleFact), nameof(AngleFact))]
[JsonSubtypes.KnownSubType(typeof(CircleFact), nameof(CircleFact))]
[JsonSubtypes.KnownSubType(typeof(ParallelLineFact), nameof(ParallelLineFact))]
[JsonSubtypes.KnownSubType(typeof(OnCircleFact), nameof(OnCircleFact))]
[JsonSubtypes.KnownSubType(typeof(AngleCircleLineFact), nameof(AngleCircleLineFact))]
[JsonSubtypes.KnownSubType(typeof(OrthogonalCircleLineFact), nameof(OrthogonalCircleLineFact))]
[JsonSubtypes.KnownSubType(typeof(AreaCircleFact), nameof(AreaCircleFact))]
[JsonSubtypes.KnownSubType(typeof(RadiusFact), nameof(RadiusFact))]
[JsonSubtypes.KnownSubType(typeof(ConeVolumeFact), nameof(ConeVolumeFact))]
[JsonSubtypes.KnownSubType(typeof(TruncatedConeVolumeFact), nameof(TruncatedConeVolumeFact))]
[JsonSubtypes.KnownSubType(typeof(RightAngleFact), nameof(RightAngleFact))]
[JsonSubtypes.KnownSubType(typeof(CylinderVolumeFact), nameof(CylinderVolumeFact))]
[JsonSubtypes.KnownSubType(typeof(TestFact), nameof(TestFact))]
[JsonSubtypes.KnownSubType(typeof(EqualCirclesFact), nameof(EqualCirclesFact))]
[JsonSubtypes.KnownSubType(typeof(UnEqualCirclesFact), nameof(UnEqualCirclesFact))]
[JsonSubtypes.KnownSubType(typeof(AttachedPositionFunction), nameof(AttachedPositionFunction))]
//[JsonSubtypes.KnownSubType(typeof(FunctionFact<T0, TResult>), "FunctionFact<T0, TResult>")] //TODO: generics? => nameof doesnot work (generic agnostic)
[JsonSubtypes.KnownSubType(typeof(FunctionFact<float, float>), "FunctionFact<System.Single, System.Single>")]
[JsonSubtypes.KnownSubType(typeof(FunctionFactFloat<Vector3>), "FunctionFact<System.Single, UnityEngine.Vector3>")]
/// <summary>
/// Reference to <c>GameObject</c> that represents this Fact in the GameWorld.
/// </summary>
/// <seealso cref="FactObject"/>
public GameObject Representation;
/// <summary>
/// Collection of <c>Type</c>s of *all* available <see cref="Fact"/>s to choose from.
/// </summary>
[JsonIgnore]
public static readonly Type[] Types = TypeExtensions<Fact>.UAssemblyInheritenceTypes;
Marco Zimmer
committed
/// <value>
/// [ClassName] for JSON de-/serialization.
/// Automatically set in <see cref="Fact()"/> for <b>NON-Generiy-Types</b>!
/// Also add JsonSubtypes.KnownSubType decorator for deserialization to Fact!
Marco Zimmer
committed
/// </value>
protected string s_type;
Marco Zimmer
committed
/// <value>
/// Unique Id. e.g.: MMT URI
/// </value>
set { _URI ??= value; } // needed for JSON
/// <summary>
/// MMT URI
/// </summary>
Marco Zimmer
committed
/// <value>
/// <c>get</c> initiates and subsequently updates a human readable name. <remarks>Should be called once a constructor call to be initiated.</remarks>
/// <c>set</c> calls <see cref="rename(string)"/>
/// </value>
public string Label
{
get
{ // in case of renamed dependables
return _Facts == null // JsonSerialization toggle (_Facts.GetNumberOfFacts() == 0 && this is not PointFact) // JsonSerialization toggle && allow first (Point)Fact to be created
|| (hasCustomLabel && _CustomLabel != null)
Marco Zimmer
committed
? _CustomLabel
: generateLabel();
Marco Zimmer
committed
}
set
{
if (_Facts == null) // JsonSerialization toggle)
{
_CustomLabel = value;
LabelId = -LabelId;
return;
}
/// <value>
/// Is true if Fact has a custom <see cref="Label"/> which is not <c>null</c> or <c>""</c>.
/// </value>
public bool hasCustomLabel => LabelId < 0;
/// <summary>
/// Stores custom <see cref="Label"/> if set.
/// </summary>
Marco Zimmer
committed
protected string _CustomLabel = null;
/// <summary>
/// Counter to organize auto generated <see cref="Label"/>.
/// Set to negative, if custom \ref Label is assigned.
/// </summary>
// property for JSON to set AFTER Label => declare AFTER Label
public int LabelId { get; set; }
/// <summary>
/// Reference to <see cref="FactOrganizer"/> in which this Fact and all its <see cref="getDependentFactIds">depending Facts</see> are beeing organized.
/// </summary>
MaZiFAU
committed
[JsonIgnore]
protected FactOrganizer _Facts;
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
public Vector3 Position
{
get
{
if (ForceRecalculateTransform)
RecalculateTransform();
return _Position;
}
protected set
{
ForceRecalculateTransform = false;
_Position = value;
}
}
private Vector3 _Position;
[JsonIgnore]
public Quaternion Rotation
{
get
{
if (ForceRecalculateTransform)
RecalculateTransform();
return _Rotation;
}
protected set
{
ForceRecalculateTransform = false;
_Rotation = value;
}
}
private Quaternion _Rotation;
public Vector3 LocalScale
{
get
{
if (ForceRecalculateTransform)
RecalculateTransform();
return _LocalScale;
}
protected set
{
ForceRecalculateTransform = false;
_LocalScale = value;
}
}
private Vector3 _LocalScale;
/// <summary>
/// Only being used by [JsonReader](https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonReader.htm) to initiate empty \ref Fact "Facts".
MaZiFAU
committed
/// <seealso cref="SOMDocManager"/>
/// </summary>
protected Fact()
{
s_type = this.GetType().Name;
/// <summary>
/// Standard base-constructor.
/// </summary>
/// <param name="organizer"><see cref="_Facts"/></param>
protected Fact(FactOrganizer organizer) : this()
{
this._Facts = organizer;
}
/// <summary>
/// Copies <paramref name="fact"/> by initiating new MMT %Fact.
/// </summary>
/// <param name="fact">Fact to be copied</param>
/// <param name="old_to_new"><c>Dictionary</c> mapping <paramref name="fact"/>.<see cref="getDependentFactIds"/> in <paramref name="fact"/>.<see cref="Fact._Facts"/> to corresponding <see cref="Fact.Id"/> in <paramref name="organizer"/> </param>
/// <param name="organizer"><see cref="_Facts"/></param>
public Fact ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
ret.LabelId = this.LabelId;
if (ret.hasCustomLabel)
ret._CustomLabel = this.Label;
return ret;
protected abstract Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer);
/// <summary>
/// Assignes a custom <see cref="Label"/>, if <paramref name="newLabel"/> is not yet taken;
/// or clears custom <see cref="Label"/>.
/// </summary>
/// <param name="newLabel">To be new <see cref="Label"/>. To reset to auto-generation set to <c>null</c> or <c>""</c>.</param>
/// <returns></returns>
//TODO: notify about updated dependable Labelnames for UI
//TODO: check for colissions with not yet generated names
public bool rename(string newLabel)
// returns true if succeded
{
if (string.IsNullOrEmpty(newLabel) && _Facts.GetNumberOfFacts() != 0)
// switch back to autogenerated
{
generateLabel();
_CustomLabel = null;
return true;
}
else
// set CustomLabel if available
{
if (_Facts.ContainsLabel(newLabel))
return false;
freeAutoLabel();
_CustomLabel = newLabel;
Marco Zimmer
committed
/// <returns><see langword="true"/> if Fact depends on other \ref Fact "Facts"; equivalent to <see cref="getDependentFactIds"/> returns non empty array</returns>
Marco Zimmer
committed
public abstract bool hasDependentFacts();
/// <returns> array of Fact <see cref="Id"> Ids </see> on which this Fact depends.</returns>
/// <example><see cref="AngleFact"/> needs 3 <see cref="PointFact"/>s to be defined.</example>
public abstract string[] getDependentFactIds();
/// <summary>
/// Initiates a <paramref name="prefab"/> at <paramref name="transform"/> e.g. by setting <see cref="Label"/>.
/// </summary>
/// <remarks>Does not set <see cref="Representation"/>.</remarks>
/// <param name="prefab"><c>GameObject</c> Prefab that will represent this Fact</param>
/// <param name="transform"><c>Transform</c> where to initiate <paramref name="prefab"/></param>
/// <returns></returns>
// TODO: set Representation here instead of ...
public abstract GameObject instantiateDisplay(GameObject prefab, Transform transform);
protected abstract MMTDeclaration MakeMMTDeclaration();
/// <summary>
/// Frees ressources e.g. <see cref="Label"/> and will eventually delete %Fact Server-Side in far-near future when feature is supported.
/// </summary>
Marco Zimmer
committed
Marco Zimmer
committed
Marco Zimmer
committed
if (VerboseURI)
Marco Zimmer
committed
Debug.Log("Server removed Fact:\n" + this.Id);
/// <summary>
/// Compares \ref Fact "this" against <paramref name="f2"/>.
/// </summary>
/// <param name="f2">Fact to compare to</param>
/// <returns><c>true</c> if <paramref name="f2"/> is semantical very similar to \ref Fact "this"</returns>
Marco Zimmer
committed
public abstract bool Equivalent(Fact f2);
/// <summary>
/// Compares <paramref name="f1"/> against <paramref name="f2"/>.
/// </summary>
/// <param name="f1">Fact to compare to</param>
/// <param name="f2">Fact to compare to</param>
/// <returns><c>true</c> if <paramref name="f2"/> is semantical very similar to <paramref name="f1"/></returns>
Marco Zimmer
committed
public abstract bool Equivalent(Fact f1, Fact f2);
/// <summary>
/// canonical
/// </summary>
/// <returns>unique-ish Hash</returns>
public new virtual int GetHashCode()
=> getDependentFactIds()
.Select(id => id.GetHashCode())
.Aggregate((hash1, hash2) => hash1 ^ hash2);
/// <summary>
/// auto-generates <see cref="Label"/> using generation variable(s) e.g. <see cref="LabelId"/>;
/// if custom <see cref="Label"/> is set, tries to restore original generated <see cref="Label"/> **without** resetting <see cref="_CustomLabel"/>. If original <see cref="Label"/> is already taken, a new one will be generated.
/// </summary>
/// <returns>auto-generated <see cref="Label"/></returns>
Marco Zimmer
committed
protected virtual string generateLabel()
{
LabelId = _Facts.UnusedLabelIds.Remove(-LabelId) ? -LabelId : 0;
Marco Zimmer
committed
if (LabelId == 0)
if (_Facts.UnusedLabelIds.Count == 0)
LabelId = ++_Facts.MaxLabelId;
Marco Zimmer
committed
else
{
LabelId = _Facts.UnusedLabelIds.Min;
_Facts.UnusedLabelIds.Remove(LabelId);
Marco Zimmer
committed
}
return ((char)(64 + LabelId)).ToString();
}
/// <summary>
/// Parses <see cref="Scroll.ScrollFact"/> to actual Fact
/// </summary>
/// <param name="fact">instance to be parsed</param>
/// <returns>parsed Fact</returns>
public static Fact parseFact(Scroll.ScrollFact fact)
/// <summary>
/// Tries to find <see cref="Fact.Id"/> in the global space.
/// </summary>
/// <param name="URI"><see cref="Fact.Id"/> to search for</param>
/// <param name="found"><see cref="Fact"/> iff found, else <c>null</c></param>
/// <returns></returns>
public static bool TryGetGlobalFact(string URI, out Fact found)
=> StageStatic.stage.factState.TryGetFact(URI, out found);
/// <summary>
/// Tells <see cref="_Facts"/> that \ref Fact "this" no longer uses auto-generated <see cref="Label"/>, but remembers current generation variable(s).
/// </summary>
// TODO? only get _Fact to freeLabel/
public /*protected internal*/ void freeAutoLabel()
{
if (LabelId > 0)
_Facts.UnusedLabelIds.Add(LabelId);
// store Label for name-persistance
Marco Zimmer
committed
LabelId = -LabelId;
}
/// <summary>
/// Implements CRTP for <see cref="Fact"/>; Escalates constructors;
/// </summary>
/// <typeparam name="T">class, which inherits from FactWrappedCRTP</typeparam>
public abstract class FactWrappedCRTP<T> : Fact where T : FactWrappedCRTP<T>
/// <summary>\copydoc Fact.Fact()</summary>
protected FactWrappedCRTP() : base() { }
/// <summary>\copydoc Fact.Fact(FactOrganizer)</summary>
protected FactWrappedCRTP(FactOrganizer organizer) : base(organizer) { }
/// \copydoc Fact.Equivalent(Fact)
Marco Zimmer
committed
public override bool Equivalent(Fact f2)
Marco Zimmer
committed
/// \copydoc Fact.Equivalent(Fact, Fact)
Marco Zimmer
committed
public override bool Equivalent(Fact f1, Fact f2)
=> f1.GetType() == f2.GetType() && EquivalentWrapped((T)f1, (T)f2);
Marco Zimmer
committed
/// <summary>CRTP step of <see cref="Equivalent(Fact)"/> and <see cref="Equivalent(Fact, Fact)"/></summary>
Marco Zimmer
committed
protected abstract bool EquivalentWrapped(T f1, T f2);
protected bool DependentFactsEquivalent(T f1, T f2)
=> f1.getDependentFactIds()
.Zip(f2.getDependentFactIds(),
(id1, id2) =>
id1.Equals(id2)
|| FactOrganizer.AllFacts[id1].Equivalent(FactOrganizer.AllFacts[id2])
)
.All(b => b);
Marco Zimmer
committed
}
/// <summary>
/// Point in 3D Space
/// </summary>
Marco Zimmer
committed
public class PointFact : FactWrappedCRTP<PointFact>
/// <summary> Position </summary>
/// <summary> Orientation for <see cref="Fact.Representation"/> </summary>
public Vector3 Normal;
/// <summary> \copydoc Fact.Fact </summary>
public PointFact() : base()
{
this.Point = Vector3.zero;
this.Normal = Vector3.zero;
}
/// <summary>
/// Standard Constructor:
/// Initiates <see cref="Point"/>, <see cref="Normal"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
/// </summary>
/// <param name="P">sets <see cref="Point"/></param>
/// <param name="N">sets <see cref="Normal"/></param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public PointFact(Vector3 P, Vector3 N, FactOrganizer organizer) : base(organizer)
this.Point = P;
this.Normal = N;
AddFactResponse.sendAdd(MakeMMTDeclaration(), out this._URI);
{
Position = Point;
Rotation = Quaternion.LookRotation(Normal);
}
/// <summary>
/// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
/// <see cref="Normal"/> set to <c>Vector3.up</c>
/// </summary>
/// <param name="a">sets <c>x</c> coordinate of <see cref="Point"/></param>
/// <param name="b">sets <c>y</c> coordinate of <see cref="Point"/></param>
/// <param name="c">sets <c>z</c> coordinate of <see cref="Point"/></param>
/// <param name="uri">MMT URI</param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public PointFact(float a, float b, float c, string uri, FactOrganizer organizer) : base(organizer)
this.Normal = Vector3.up;
/// \copydoc Fact.parseFact(Scroll.ScrollFact)
public new static PointFact parseFact(Scroll.ScrollFact fact)
{
string uri = fact.@ref.uri;
OMA df = (OMA)((Scroll.ScrollSymbolFact)fact).df;
string parse_id = df.ToString();
if (!ParsingDictionary.parseTermsToId.ContainsKey(parse_id))
ParsingDictionary.parseTermsToId[parse_id] = uri;
float a = ((OMF)df.arguments[0]).f;
float b = ((OMF)df.arguments[1]).f;
float c = ((OMF)df.arguments[2]).f;
return new PointFact(a, b, c, uri, StageStatic.stage.factState);
/// \copydoc Fact.hasDependentFacts
public override Boolean hasDependentFacts()
=> false;
/// \copydoc Fact.getDependentFactIds
public override string[] getDependentFactIds()
=> new string[] { };
/// \copydoc Fact.instantiateDisplay(GameObject, Transform)
public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
{
var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = this.Label;
obj.GetComponent<FactWrapper>().fact = this;
return obj;
}
/// \copydoc Fact.GetHashCode
Marco Zimmer
committed
public override int GetHashCode()
=> this.Point.GetHashCode() ^ this.Normal.GetHashCode();
/// \copydoc Fact.Equivalent(Fact, Fact)
Marco Zimmer
committed
protected override bool EquivalentWrapped(PointFact f1, PointFact f2)
=> Math3d.IsApproximatelyEqual(f1.Point, f2.Point);
protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
=> new PointFact(this.Point, this.Normal, organizer);
protected override MMTDeclaration MakeMMTDeclaration()
{
SOMDoc tp = new OMS(MMT_OMS_URI.Point);
SOMDoc df = new OMA(
new OMS(MMT_OMS_URI.Tuple),
new List<SOMDoc> {
new OMF(Point.x),
new OMF(Point.y),
new OMF(Point.z),
}
);
ParsingDictionary.parseTermsToId[df.ToString()] = _URI;
return new MMTSymbolDeclaration(Label, tp, df);
}
/// <summary>
/// A <see cref="PointFact"/> on a <see cref="AbstractLineFact"/>
/// </summary>
Marco Zimmer
committed
public class OnLineFact : FactWrappedCRTP<OnLineFact>
{
MaZiFAU
committed
/// <summary> <see cref="PointFact"/>.<see cref="Fact.Id">Id</see> </summary>
public string Pid;
[JsonIgnore]
public PointFact Point { get => (PointFact)FactOrganizer.AllFacts[Pid]; }
MaZiFAU
committed
/// <summary> <see cref="AbstractLineFact"/>.<see cref="Fact.Id">Id</see> </summary>
public string Rid;
[JsonIgnore]
public AbstractLineFact Ray { get => (AbstractLineFact)FactOrganizer.AllFacts[Rid]; }
/// <summary> \copydoc Fact.Fact </summary>
public OnLineFact() : base()
{
this.Pid = null;
this.Rid = null;
}
/// <summary>
/// Standard Constructor:
/// Initiates <see cref="Pid"/>, <see cref="Rid"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
/// </summary>
/// <param name="pid">sets <see cref="Pid"/></param>
/// <param name="rid">sets <see cref="Rid"/></param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public OnLineFact(string pid, string rid, FactOrganizer organizer) : base(organizer)
{
this.Pid = pid;
this.Rid = rid;
AddFactResponse.sendAdd(MakeMMTDeclaration(), out this._URI);
}
{
Position = Point.Position;
{ //Rotation
Vector3 up = Point.Normal;
Vector3 forward = Ray.Dir;
if (Math3d.IsApproximatelyEqual(up, forward))
{
Vector3 arbitary = Math3d.IsApproximatelyEqual(forward, Vector3.forward)
? Vector3.right
: Vector3.forward;
up = Vector3.Cross(arbitary, forward);
}
Rotation = Quaternion.LookRotation(forward, up);
}
}
/// <summary>
/// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
/// </summary>
/// <param name="pid">sets <see cref="Pid"/></param>
/// <param name="rid">sets <see cref="Rid"/></param>
/// <param name="uri">MMT URI</param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public OnLineFact(string pid, string rid, string uri, FactOrganizer organizer) : base(organizer)
this.Pid = pid;
this.Rid = rid;
}
/// \copydoc Fact.parseFact(Scroll.ScrollFact)
public new static OnLineFact parseFact(Scroll.ScrollFact fact)
{
string pointUri = ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).uri;
string lineUri = ((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[0] is OMS
? ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[0]).uri
// case when line Uri has a projl on the line Argument
: ((OMS)((OMA)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[0]).arguments[0]).uri;
Marco Zimmer
committed
if (StageStatic.stage.factState.ContainsKey(pointUri)
&& StageStatic.stage.factState.ContainsKey(lineUri))
return new OnLineFact(pointUri, lineUri, uri, StageStatic.stage.factState);
//If dependent facts do not exist return null
}
/// \copydoc Fact.generateLabel
protected override string generateLabel()
/// \copydoc Fact.hasDependentFacts
/// \copydoc Fact.getDependentFactIds
public override string[] getDependentFactIds()
/// \copydoc Fact.instantiateDisplay(GameObject, Transform)
public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
{
var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Point.Label;
obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Ray.Label;
obj.GetComponent<FactWrapper>().fact = this;
return obj;
}
Marco Zimmer
committed
protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2)
protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
=> new OnLineFact(old_to_new[this.Pid], old_to_new[this.Rid], organizer);
protected override MMTDeclaration MakeMMTDeclaration()
{
SOMDoc tp = new OMA(
new OMS(MMT_OMS_URI.Ded),
new List<SOMDoc> {
new OMA(
new OMS(MMT_OMS_URI.OnLine),
new List<SOMDoc> {
new OMS(Rid),
new OMS(Pid)
}),});
SOMDoc df = null;
return new MMTSymbolDeclaration(this.Label, tp, df);
}
}
/// <summary>
/// Two parallel Lines comprised of two <see cref="LineFact">LineFacts</see>
/// </summary>
public class ParallelLineFact : FactWrappedCRTP<ParallelLineFact>
{
/// @{ <summary>
MaZiFAU
committed
/// One <see cref="Fact.Id">Id</see> of two <see cref="LineFact"/> that are parallel [<see cref="Lid1"/>, <see cref="Lid2"/>].
/// </summary>
public string Lid1, Lid2;
/// @}
MaZiFAU
committed
[JsonIgnore]
public AbstractLineFact Ray1 { get => (AbstractLineFact)FactOrganizer.AllFacts[Lid1]; }
MaZiFAU
committed
[JsonIgnore]
public AbstractLineFact Ray2 { get => (AbstractLineFact)FactOrganizer.AllFacts[Lid2]; }
/// <summary> \copydoc Fact.Fact </summary>
public ParallelLineFact() : base()
{
this.Lid1 = null;
this.Lid2 = null;
}
/// <summary>
/// Standard Constructor
/// </summary>
/// <param name="lid1">sets <see cref="Lid1"/></param>
/// <param name="lid2">sets <see cref="Lid2"/></param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public ParallelLineFact(string lid1, string lid2, FactOrganizer organizer) : base(organizer)
{
this.Lid1 = lid1;
this.Lid2 = lid2;
AddFactResponse.sendAdd(MakeMMTDeclaration(), out this._URI);
/// <summary>
/// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
/// </summary>
/// <param name="Lid1">sets <see cref="Lid1"/></param>
/// <param name="Lid2">sets <see cref="Lid2"/></param>
/// <param name="backendURI">MMT URI</param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public ParallelLineFact(string Lid1, string Lid2, string backendURI, FactOrganizer organizer) : base(organizer)
{
this.Lid1 = Lid1;
this.Lid2 = Lid2;
this._URI = backendURI;
_ = this.Label;
}
/// \copydoc Fact.parseFact(Scroll.ScrollFact)
public new static ParallelLineFact parseFact(Scroll.ScrollFact fact)
{
OMA tp = (OMA)((Scroll.ScrollSymbolFact)fact).tp;
if (tp == null)
return null;
string uri = fact.@ref.uri;
string lineAUri;
string lineBUri;
OMA proof_OMA = (OMA)((Scroll.ScrollSymbolFact)fact).tp; // proof DED
OMA parallel_lines_OMA = (OMA)proof_OMA.arguments[0]; // parallel
if (parallel_lines_OMA.arguments[0] is OMS)
{ // Normaler Fall
lineAUri = ((OMS)parallel_lines_OMA.arguments[0]).uri;
lineBUri = ((OMS)parallel_lines_OMA.arguments[1]).uri;
else // TODO: Second case might be redundant by now
{
OMA Projl_line_A_OMA = (OMA)parallel_lines_OMA.arguments[0]; // ProjectL
lineAUri = ((OMS)Projl_line_A_OMA.arguments[0]).uri;
OMA Projl_line_B_OMA = (OMA)parallel_lines_OMA.arguments[1]; // ProjectL
lineBUri = ((OMS)Projl_line_B_OMA.arguments[0]).uri;
}
if (StageStatic.stage.factState.ContainsKey(lineAUri)
&& StageStatic.stage.factState.ContainsKey(lineBUri))
return new ParallelLineFact(lineAUri, lineBUri, uri, StageStatic.stage.factState);
else //If dependent facts do not exist return null
return null;
}
/// \copydoc Fact.generateLabel
protected override string generateLabel()
protected override MMTDeclaration MakeMMTDeclaration()
MaZiFAU
committed
SOMDoc tp = new OMA(
new OMS(MMT_OMS_URI.Ded),
new List<SOMDoc> {
MaZiFAU
committed
new OMS(MMT_OMS_URI.ParallelLine),
new List<SOMDoc> {
new OMS(Lid1),
new OMS(Lid2),
MaZiFAU
committed
SOMDoc df = null;
return new MMTSymbolDeclaration(this.Label, tp, df);
}
/// \copydoc Fact.hasDependentFacts
public override Boolean hasDependentFacts()
/// \copydoc Fact.getDependentFactIds
public override string[] getDependentFactIds()
/// \copydoc Fact.instantiateDisplay(GameObject, Transform)
public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
{
var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Ray1.Label;
obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Ray2.Label;
obj.GetComponent<FactWrapper>().fact = this;
return obj;
}
/// \copydoc Fact.Equivalent(Fact, Fact)
protected override bool EquivalentWrapped(ParallelLineFact f1, ParallelLineFact f2)
protected override Fact _ReInitializeMe(Dictionary<string, string> old_to_new, FactOrganizer organizer)
=> new ParallelLineFact(old_to_new[this.Lid1], old_to_new[this.Lid2], organizer);
/// A Circle that is made out of a middle point, a plane and a radius
/// </summary>
public class CircleFact : FactWrappedCRTP<CircleFact>
{
/// <summary> defining the middle point of the circle </summary>
public string Pid1;
/// <summary> defining the base point of the circle plane </summary>
public string Pid2;
MaZiFAU
committed
[JsonIgnore]
public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
MaZiFAU
committed
[JsonIgnore]
public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
MaZiFAU
committed
/// <summary> radius of the circle </summary>
public float radius;
/// <summary> normal vector of the plane </summary>
public Vector3 normal;
/// <summary> \copydoc Fact.Fact </summary>
public CircleFact() : base()
{
this.normal = Vector3.zero;
this.Pid1 = null;
this.Pid2 = null;
this.radius = 0;
}
/// <summary>
/// Standard Constructor:
/// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="radius"/>,<see cref="dir1"/>,<see cref="dir2"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
/// </summary>
/// <param name="pid1">sets <see cref="Pid1"/></param>
/// <param name="pid2">sets <see cref="Pid2"/></param>
/// <param name="radius">sets <see cref="radius"/></param>
/// <param name="normal">sets <see cref="normal"/></param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public CircleFact(string pid1, string pid2, float radius, Vector3 normal, FactOrganizer organizer) : base(organizer)
{
this.Pid1 = pid1;
this.Pid2 = pid2;
this.radius = radius;
this.normal = normal;
AddFactResponse.sendAdd(MakeMMTDeclaration(), out this._URI);
{
Position = Point1.Position;
Rotation = Quaternion.LookRotation(normal);
LocalScale = new Vector3(radius, 1, radius);
}
/// <summary>
/// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
/// </summary>
/// <param name="Pid1">sets <see cref="Pid1"/></param>
/// <param name="Pid2">sets <see cref="Pid2"/></param>
/// <param name="radius">sets <see cref="radius"/></param>
/// <param name="normal">sets <see cref="normal"/></param>
/// <param name="backendURI">MMT URI</param>
/// <param name="organizer">sets <see cref="Fact._Facts"/></param>
public CircleFact(string Pid1, string Pid2, float radius, Vector3 normal, string backendURI, FactOrganizer organizer) : base(organizer)
{
this.Pid1 = Pid1;
this.Pid2 = Pid2;
this.radius = radius;
this.normal = normal;
this._URI = backendURI;
_ = this.Label;
}
/// <summary>
/// parses the Circlefact response of the MMT-Server
/// </summary>
/// \copydoc Fact.parseFact(Scroll.ScrollFact)
public new static CircleFact parseFact(Scroll.ScrollFact fact)
{
string uri = fact.@ref.uri;
OMA df = (OMA)((Scroll.ScrollSymbolFact)fact).df;
if (df == null)
return null;
Scroll.ScrollSymbolFact scoll_symbol_fact = (Scroll.ScrollSymbolFact)fact;
float radius = ((OMF)((OMA)scoll_symbol_fact.df).arguments[2]).f;
OMA planeOMA = (OMA)((OMA)scoll_symbol_fact.df).arguments[0];