feat: validate p-rec-annot connector view eligibility
This commit is contained in:
@@ -122,6 +122,7 @@ public interface IPlantConnectorPortReader
|
||||
{
|
||||
PlantConnectorPortReadResult Read(PlantConnectorRelationshipSnapshot connector);
|
||||
}
|
||||
public sealed record ConnectorViewportEligibility(bool Eligible, Point3Dto? PlacementPoint, string? FailureCode = null);
|
||||
public sealed record LineNumberOwnedRow(string SourceStableId, int MarkerNumber, string Text, AnnotationPoint MarkerAttributePosition);
|
||||
public sealed record LineNumberRowMutation(string SourceStableId, int PreviousMarkerNumber, int MarkerNumber, string Text, AnnotationPoint? MarkerAttributePosition);
|
||||
public sealed record LineNumberTextAsset(string Layer, string TextStyle, double Size, string TextValue, Point2Dto Position);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using PRecAnnot.Abstractions;
|
||||
|
||||
namespace PRecAnnot.Core;
|
||||
|
||||
// Port of AutoLinenumberConnections.IsOKPrepareAnnotation's geometry gate.
|
||||
// The caller performs model-to-paper transformation only after the connector
|
||||
// is eligible, preserving legacy model-space containment semantics.
|
||||
public sealed class ConnectorViewportEligibilityEvaluator
|
||||
{
|
||||
public ConnectorViewportEligibility Evaluate(PlantConnectorPortSnapshot ports, Point3Dto viewDirection, Bounds3Dto viewExtents, double parallelTolerance = 0.1)
|
||||
{
|
||||
if (parallelTolerance < 0) throw new ArgumentOutOfRangeException(nameof(parallelTolerance));
|
||||
if (Parallel(ports.FirstDirection, viewDirection, parallelTolerance) || Parallel(ports.SecondDirection, viewDirection, parallelTolerance))
|
||||
return new(false, null, "CONNECTOR_PORT_PARALLEL_TO_VIEW");
|
||||
if (!Inside(ports.FirstPosition, viewExtents) || !Inside(ports.SecondPosition, viewExtents))
|
||||
return new(false, null, "CONNECTOR_OUTSIDE_VIEW_EXTENTS");
|
||||
// Legacy stores ports[1] as the insertion/model anchor.
|
||||
return new(true, ports.SecondPosition);
|
||||
}
|
||||
|
||||
private static bool Inside(Point3Dto point, Bounds3Dto bounds) =>
|
||||
point.X >= bounds.Minimum.X && point.X <= bounds.Maximum.X &&
|
||||
point.Y >= bounds.Minimum.Y && point.Y <= bounds.Maximum.Y &&
|
||||
point.Z >= bounds.Minimum.Z && point.Z <= bounds.Maximum.Z;
|
||||
|
||||
private static bool Parallel(Point3Dto first, Point3Dto second, double tolerance)
|
||||
{
|
||||
var firstLength = Math.Sqrt(first.X * first.X + first.Y * first.Y + first.Z * first.Z);
|
||||
var secondLength = Math.Sqrt(second.X * second.X + second.Y * second.Y + second.Z * second.Z);
|
||||
if (firstLength == 0 || secondLength == 0) return true;
|
||||
var cosine = Math.Abs((first.X * second.X + first.Y * second.Y + first.Z * second.Z) / (firstLength * secondLength));
|
||||
return 1d - cosine <= tolerance;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user