<> <> <> <Documentation>MultiGravity.tioga.>> <<>> DIRECTORY GGBasicTypes, AtomButtons, GGCaret, GGCircles, GGLines, GGInterfaceTypes, GGModelTypes, GGMultiGravity, GGSegmentTypes, GGStatistics, GGUtility, GGVector, RealFns, Rope; GGMultiGravityImpl: CEDAR PROGRAM IMPORTS AtomButtons, GGCaret, GGCircles, GGLines, GGStatistics, GGVector, RealFns EXPORTS GGMultiGravity = BEGIN Arc: TYPE = GGBasicTypes.Arc; AlignmentCircle: TYPE = GGInterfaceTypes.AlignmentCircle; AlignmentLine: TYPE = GGInterfaceTypes.AlignmentLine; AlignmentPoint: TYPE = REF AlignmentPointObj; AlignmentPointObj: TYPE = GGInterfaceTypes.AlignmentPointObj; Caret: TYPE = GGInterfaceTypes.Caret; Circle: TYPE = GGBasicTypes.Circle; Edge: TYPE = GGBasicTypes.Edge; FeatureData: TYPE = REF FeatureDataObj; FeatureDataObj: TYPE = GGModelTypes.FeatureDataObj; GargoyleData: TYPE = GGInterfaceTypes.GargoyleData; GoodCurve: TYPE = REF GoodCurveObj; GoodCurveObj: TYPE = GGMultiGravity.GoodCurveObj; GoodPoint: TYPE = REF GoodPointObj; GoodPointObj: TYPE = GGMultiGravity.GoodPointObj; GoodPointType: TYPE = GGMultiGravity.GoodPointType; JointGenerator: TYPE = GGModelTypes.JointGenerator; Line: TYPE = GGBasicTypes.Line; NearDistances: TYPE = REF NearDistancesObj; NearDistancesObj: TYPE = GGMultiGravity.NearDistancesObj; NearFeatures: TYPE = REF NearFeaturesObj; NearFeaturesObj: TYPE = GGMultiGravity.NearFeaturesObj; NearPoints: TYPE = REF NearPointsObj; NearPointsAndCurves: TYPE = REF NearPointsAndCurvesObj; NearPointsAndCurvesObj: TYPE = GGMultiGravity.NearPointsAndCurvesObj; NearPointsObj: TYPE = GGMultiGravity.NearPointsObj; ObjectBag: TYPE = REF ObjectBagObj; ObjectBagObj: TYPE = GGInterfaceTypes.ObjectBagObj; Outline: TYPE = GGModelTypes.Outline; OutlineDescriptor: TYPE = REF OutlineDescriptorObj; OutlineDescriptorObj: TYPE = GGModelTypes.OutlineDescriptorObj; Point: TYPE = GGBasicTypes.Point; Segment: TYPE = GGSegmentTypes.Segment; SegmentGenerator: TYPE = GGModelTypes.SegmentGenerator; Sequence: TYPE = GGModelTypes.Sequence; Slice: TYPE = GGModelTypes.Slice; SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor; TriggerBag: TYPE = REF TriggerBagObj; TriggerBagObj: TYPE = GGInterfaceTypes.TriggerBagObj; MultiGravityPool: TYPE = REF MultiGravityPoolObj; MultiGravityPoolObj: TYPE = RECORD [ distances: NearDistances, features: NearFeatures, bestpoints: BestPoints, bestcurves: BestCurves ]; BestCurves: TYPE = REF BestCurvesObj; BestCurvesObj: TYPE = RECORD [ size: NAT, max, min: REAL, overflow: BOOL, curves: SEQUENCE len: NAT OF GoodCurve]; BestPoints: TYPE = REF BestPointsObj; BestPointsObj: TYPE = RECORD [ size: NAT, max, min: REAL, overflow: BOOL, points: SEQUENCE len: NAT OF GoodPoint]; <> <<>> EmptyBag: PROC [objectBag: ObjectBag] RETURNS [BOOL] = { RETURN[ objectBag.slopeLines = NIL AND objectBag.angleLines = NIL AND objectBag.radiiCircles = NIL AND objectBag.distanceLines = NIL AND objectBag.midpoints = NIL AND objectBag.intersectionPoints = NIL]; }; EmptyTriggers: PROC [triggerBag: TriggerBag] RETURNS [BOOL] = { RETURN[ triggerBag.outlines = NIL AND triggerBag.slices = NIL AND triggerBag.intersectionPoints = NIL AND triggerBag.anchor = NIL ]; }; Problem: PUBLIC SIGNAL [msg: Rope.ROPE] = CODE; <> << [Artwork node; type 'ArtworkInterpress on' to command tool] >> <> Map: PUBLIC PROC [testPoint: Point, criticalR: REAL, currentObjects: ObjectBag, activeObjects: TriggerBag, gargoyleData: GargoyleData, intersections: BOOL] RETURNS [resultPoint: Point, feature: FeatureData] = { <> ENABLE UNWIND => gargoyleData.multiGravityPool _ NewMultiGravityPool[]; -- in case an ABORT happened while pool was in use GGStatistics.StartInterval[$MultiMap, GGStatistics.GlobalTable[]]; SELECT AtomButtons.GetButtonState[gargoyleData.hitTest.gravButton] FROM on => SELECT gargoyleData.hitTest.gravityType FROM strictDistance => [resultPoint, feature] _ StrictDistance[testPoint, criticalR, currentObjects, activeObjects, gargoyleData]; innerCircle => [resultPoint, feature] _ InnerCircle[testPoint, criticalR, gargoyleData.hitTest.innerR, currentObjects, activeObjects, gargoyleData, intersections]; ENDCASE => ERROR; off => { resultPoint _ testPoint; feature _ NIL; }; ENDCASE => ERROR; GGStatistics.StopInterval[$MultiMap, GGStatistics.GlobalTable[]]; }; <<>> PrepareWinner: PROC [nearPointsAndCurves: NearPointsAndCurves, index: NAT] RETURNS [resultPoint: Point, feature: FeatureData] = { WITH nearPointsAndCurves[index] SELECT FROM goodPoint: GoodPoint => { resultPoint _ goodPoint.point; ExtractResultFromPoint[goodPoint, goodPoint.featureData]; -- stuffs hit info into featureData feature _ goodPoint.featureData; }; goodCurve: GoodCurve => { resultPoint _ goodCurve.point; ExtractResultFromCurve[goodCurve, goodCurve.featureData]; -- stuffs hit info into featureData feature _ goodCurve.featureData; }; ENDCASE => ERROR; }; StrictDistance: PUBLIC PROC [testPoint: Point, criticalR: REAL, objectBag: ObjectBag, sceneBag: TriggerBag, gargoyleData: GargoyleData] RETURNS [resultPoint: Point, feature: FeatureData] = { <> nearPointsAndCurves: NearPointsAndCurves; count: NAT; [nearPointsAndCurves, count] _ MultiStrictDistance[testPoint, criticalR, objectBag, sceneBag, gargoyleData]; IF count = 0 THEN RETURN [testPoint, NIL]; IF count = 1 THEN RETURN PrepareWinner[nearPointsAndCurves, 0] ELSE { <> distances: NearDistances _ NARROW[gargoyleData.multiGravityPool, MultiGravityPool].distances; features: NearFeatures _ NARROW[gargoyleData.multiGravityPool, MultiGravityPool].features; nearestDist: REAL; bestSceneObject: INT; neighborCount: NAT _ 1; s: REAL = 0.072; -- 1/1000 inches FOR i: NAT IN [0..count) DO WITH nearPointsAndCurves[i] SELECT FROM goodPoint: GoodPoint => { distances[i] _ goodPoint.dist; features[i] _ goodPoint.featureData}; goodCurve: GoodCurve => { distances[i] _ goodCurve.dist; features[i] _ goodCurve.featureData;}; ENDCASE => ERROR; ENDLOOP; nearestDist _ distances[0]; FOR i: NAT IN [1..count) DO IF distances[i] - nearestDist < s THEN neighborCount _ neighborCount + 1; ENDLOOP; IF neighborCount = 1 THEN RETURN PrepareWinner[nearPointsAndCurves, 0]; <> <<1) Prefer scene objects to alignment lines.>> <<2) Prefer points to lines.>> <> bestSceneObject _ -1; <> <> <