<> <> <> <> <> DIRECTORY Ascii, BasicTime, ColorTool, Feedback, GGCoreOps, Imager, ImagerColor, ImagerColorFns, ImagerColorPrivate, ImagerInterpress, IO, NamedColors, PrincOpsUtils, Rope, SV2d, SV3d, SVArtwork, SVAssembly, SVBasicTypes, SVCaret, SVCastRays, SVCoordSys, SVEditUser, SVEvent, SVInterfaceTypes, SVMasterObject, SVMasterObjectTypes, SVMatrix3d, SVModelTypes, SVPreprocess3d, SVRay, SVRefresh, SVScene, SVSceneToTree, SVSceneTypes, SVSelect, SVSelections, SVState, SVTransforms, SVUserInput, SVUtility, SVVector3d, SVViewersOnScene, SVViewerTools, SVWindow, TIPUser, ViewerClasses, ViewerTools; SVEventImplC: CEDAR PROGRAM IMPORTS Ascii, BasicTime, ColorTool, GGCoreOps, SVCoordSys, SVSceneToTree, Feedback, Imager, ImagerColor, ImagerColorFns, ImagerColorPrivate, ImagerInterpress, IO, SVMatrix3d, NamedColors, PrincOpsUtils, SVPreprocess3d, Rope, SVArtwork, SVAssembly, SVCaret, SVCastRays, SVEditUser, SVEvent, SVRay, SVRefresh, SVScene, SVSelect, SVSelections, SVState, SVTransforms, SVUtility, SVVector3d, SVViewersOnScene, SVViewerTools, SVWindow, ViewerTools EXPORTS SVEvent = BEGIN Artwork: TYPE = SVModelTypes.Artwork; ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData; Slice: TYPE = SVSceneTypes.Slice; SliceList: TYPE = SVSceneTypes.SliceList; BoundBox: TYPE = SVBasicTypes.BoundBox; Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVSceneTypes.Classification; Color: TYPE = Imager.Color; CoordSystem: TYPE = SVModelTypes.CoordSystem; CSGTree: TYPE = SVSceneTypes.CSGTree; CylinderRec: TYPE = SVMasterObjectTypes.CylinderRec; EditToolData: TYPE = SVInterfaceTypes.EditToolData; FeedbackData: TYPE = Feedback.FeedbackData; FileCamera: TYPE = SVSceneTypes.FileCamera; FrameBox: TYPE = SVModelTypes.FrameBox; MasterObject: TYPE = SVSceneTypes.MasterObject; Matrix4by4: TYPE = SV3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Primitive: TYPE = SVSceneTypes.Primitive; Ray: TYPE = SVSceneTypes.Ray; Scene: TYPE = SVSceneTypes.Scene; SearchDepth: TYPE = SVSceneTypes.SearchDepth; Selection: TYPE = SVInterfaceTypes.Selection; SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator; Shape: TYPE = SVSceneTypes.Shape; SliceDescriptor: TYPE = SVSceneTypes.SliceDescriptor; SliceDescriptorGenerator: TYPE = SVSceneTypes.SliceDescriptorGenerator; Skitter: TYPE = SVSceneTypes.Skitter; SkitterMode: TYPE = SVSceneTypes.SkitterMode; Sphere: TYPE = SV3d.Sphere; ToolData: TYPE = SVSceneTypes.ToolData; TrigLine: TYPE = SV2d.TrigLine; Vector3d: TYPE = SV3d.Vector3d; SVData: TYPE = SVInterfaceTypes.SVData; <> StrokeColorFromColorTool: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { IF ColorToolIsBound[svData] THEN StrokeColorAux[ColorTool.GetColor[], svData]; }; StrokeColorToColorTool: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { IF ColorToolIsBound[svData] THEN { color: Imager.Color; sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, normal]; sliceD: SliceDescriptor _ SVSelect.NextSliceDescriptor[sliceDescGen]; IF sliceD=NIL THEN { Feedback.Append[svData.feedback, "Select exactly one segment for sending color to ColorTool", oneLiner]; } ELSE { color _ SVAssembly.GetStrokeColor[sliceD.slice, sliceD.parts]; IF color#NIL THEN ColorTool.SetColor[color, NIL] ELSE Feedback.Append[svData.feedback, ". . . Object has no stroke color", oneLiner]; }; }; }; PrintStrokeColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { FetchStrokeColor: PROC [sliceD: SliceDescriptor] RETURNS [color: Imager.ConstantColor] = { color _ NARROW[SVAssembly.GetStrokeColor[sliceD.slice, sliceD.parts].color]; }; PrintColorAux[svData.scene, svData.feedback, "Stroke", FetchStrokeColor]; }; StrokeColorNone: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { StrokeColorAux[NIL, svData]; }; StrokeColorGray: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { whiteness: REAL _ NARROW[event.rest.first, REF REAL]^; color: Imager.Color _ ImagerColor.ColorFromGray[1.0 - whiteness]; StrokeColorAux[color, svData]; }; StrokeColorFromSelectedName: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { name: Rope.ROPE _ IF event.rest = NIL THEN ViewerTools.GetSelectionContents[] ELSE NARROW[event.rest.first]; color: Imager.Color _ ParseColorName[name, svData.feedback]; IF color#NIL THEN StrokeColorAux[color, svData]; }; StrokeColorFromSelectedRGB: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { name: Rope.ROPE _ IF event.rest = NIL THEN ViewerTools.GetSelectionContents[] ELSE NARROW[event.rest.first]; color: Imager.Color _ ImagerColor.ColorFromRGB[RGBFromRope[name ! RGBFromRopeError => GOTO SyntaxError]]; StrokeColorAux[color, svData]; EXITS SyntaxError => {Feedback.Append[svData.feedback, "RGB Syntax is R: [0.0..1.0] G: [0.0..1.0] B: [0.0..1.0]", oneLiner]; Feedback.Blink[svData.feedback];}; }; StrokeColorAux: PROC [color: Imager.Color, svData: SVData] = { sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, normal]; FOR sliceD: SliceDescriptor _ SVSelect.NextSliceDescriptor[sliceDescGen], SVSelect.NextSliceDescriptor[sliceDescGen] UNTIL sliceD=NIL DO SVAssembly.SetStrokeColor[sliceD.slice, sliceD.parts, color]; ENDLOOP; SVWindow.RestoreScreenAndInvariants[paintAction: $ObjectChangedInPlace, svData: svData, remake: none, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; ColorToolIsBound: PROC [svData: SVData] RETURNS [BOOL _ FALSE] = TRUSTED { IF PrincOpsUtils.IsBound[LOOPHOLE[ColorTool.GetRGBValue]] THEN RETURN[TRUE]; Feedback.Append[svData.feedback, "Please start ColorTool and retry this operation", oneLiner]; }; <<>> SetDefaultStrokeColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { sliceD: SliceDescriptor; sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, normal]; IF sliceDescGen=NIL OR (sliceD _ SVSelect.NextSliceDescriptor[sliceDescGen])=NIL OR SVSelect.NextSliceDescriptor[sliceDescGen]#NIL THEN Feedback.Append[svData.feedback, "Select exactly one object for setting default line color", oneLiner] ELSE { isProcessBlack: Rope.ROPE; red, green, blue: REAL; color: Imager.ConstantColor _ NARROW[SVAssembly.GetStrokeColor[sliceD.slice, sliceD.parts]]; IF color#NIL THEN { [red,green,blue] _ GGCoreOps.ExtractRGB[color]; IF color = Imager.black THEN isProcessBlack _ " (process black)" ELSE IF ImagerColorPrivate.GrayFromColor[color]=1.0 THEN isProcessBlack _ " (CMY black)" ELSE isProcessBlack _ ""; Feedback.Append[ svData.feedback, IO.PutFR["Default Stroke Color: R: %1.3f G: %1.3f B: %1.3f CNS: %g%g", [real[red]], [real[green]], [real[blue]], [rope[NamedColors.HSLToRope[ImagerColorFns.HSLFromRGB[[red,green,blue]]]]], [rope[isProcessBlack]] ], oneLiner]; } ELSE Feedback.Append[svData.feedback, "Default Stroke Color: None", oneLiner]; svData.defaults.strokeColor _ color; }; }; ShowDefaultStrokeColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { isProcessBlack: Rope.ROPE; red, green, blue: REAL; color: Imager.ConstantColor _ NARROW[svData.defaults.strokeColor]; IF color#NIL THEN { [red,green,blue] _ GGCoreOps.ExtractRGB[color]; IF color = Imager.black THEN isProcessBlack _ " (process black)" ELSE IF ImagerColorPrivate.GrayFromColor[color]=1.0 THEN isProcessBlack _ " (CMY black)" ELSE isProcessBlack _ ""; Feedback.Append[ svData.feedback, IO.PutFR["Default Stroke Color: R: %1.3f G: %1.3f B: %1.3f CNS: %g%g", [real[red]], [real[green]], [real[blue]], [rope[NamedColors.HSLToRope[ImagerColorFns.HSLFromRGB[[red,green,blue]]]]], [rope[isProcessBlack]] ], oneLiner]; } ELSE Feedback.Append[svData.feedback, "Default Stroke Color: None", oneLiner]; }; <<>> <> AreaColorFromColorTool: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { IF ColorToolIsBound[svData] THEN AreaColorAux[ColorTool.GetColor[], svData]; }; AreaColorToColorTool: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { FetchFillColor: PROC [sliceD: SliceDescriptor] RETURNS [color: Imager.ConstantColor] = { color _ NARROW[SVAssembly.GetFillColor[sliceD.slice, sliceD.parts].color]; }; IF ColorToolIsBound[svData] THEN { color: Imager.Color; sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, normal]; sliceD: SliceDescriptor _ SVSelect.NextSliceDescriptor[sliceDescGen]; IF sliceD=NIL THEN { Feedback.Append[svData.feedback, "Select exactly one slice for sending color to ColorTool", oneLiner]; } ELSE { color _ FetchFillColor[sliceD]; IF color#NIL THEN ColorTool.SetColor[color, NIL] ELSE Feedback.Append[svData.feedback, ". . . Object has no fill color", oneLiner]; }; }; }; PrintAreaColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { FetchFillColor: PROC [sliceD: SliceDescriptor] RETURNS [color: Imager.ConstantColor] = { color _ NARROW[SVAssembly.GetFillColor[sliceD.slice, sliceD.parts].color]; }; PrintColorAux[svData.scene, svData.feedback, "Fill", FetchFillColor]; }; ColorFetchProc: TYPE = PROC [sliceD: SliceDescriptor] RETURNS [color: Imager.ConstantColor]; PrintColorAux: PROC [scene: Scene, feedback: FeedbackData, opName: Rope.ROPE, colorFetch: ColorFetchProc] = { sliceD: SliceDescriptor; isProcessBlack: Rope.ROPE; sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[scene, normal]; IF sliceDescGen=NIL OR (sliceD _ SVSelect.NextSliceDescriptor[sliceDescGen])=NIL OR SVSelect.NextSliceDescriptor[sliceDescGen]#NIL THEN Feedback.PutF[feedback, oneLiner, "Select exactly one object for Print%gColor", [rope[opName]]] ELSE { red, green, blue: REAL; color: Imager.ConstantColor _ colorFetch[sliceD]; IF color#NIL THEN { [red,green,blue] _ GGCoreOps.ExtractRGB[color]; IF color = Imager.black THEN isProcessBlack _ " (process black)" ELSE IF ImagerColorPrivate.GrayFromColor[color]=1.0 THEN isProcessBlack _ " (CMY black)" ELSE isProcessBlack _ ""; Feedback.Append[ feedback, IO.PutFR["R: %1.3f G: %1.3f B: %1.3f CNS: %g%g", [real[red]], [real[green]], [real[blue]], [rope[NamedColors.HSLToRope[ImagerColorFns.HSLFromRGB[[red,green,blue]]]]], [rope[isProcessBlack]] ], oneLiner]; } ELSE Feedback.PutF[feedback, oneLiner, "No %g Color", [rope[opName]]]; }; }; ParseColorName: PROC [name: Rope.ROPE, feedback: FeedbackData] RETURNS [color: Imager.Color _ NIL] ~ { IF Rope.Match["*/*", name] THEN { --try for a registered name color _ ImagerColor.Find[name]; IF color=NIL THEN color _ ImagerColor.Find[Rope.Cat["Xerox/Research/", name]]; IF color=NIL THEN GOTO UnregisteredName; } ELSE color _ ImagerColor.ColorFromRGB[ImagerColorFns.RGBFromHSL[NamedColors.RopeToHSL[name ! NamedColors.UndefinedName => GOTO UndefinedName; NamedColors.BadGrammar => GOTO BadGrammar; ]]]; EXITS UnregisteredName => {Feedback.Append[feedback, "Hierarchical name not registered", oneLiner]; Feedback.Blink[feedback];}; UndefinedName => {Feedback.Append[feedback, "Undefined Color Name", oneLiner]; Feedback.Blink[feedback];}; BadGrammar => {Feedback.Append[feedback, "Bad Color Name", oneLiner]; Feedback.Blink[feedback];}; }; AreaColorAux: PROC [color: Imager.Color, svData: SVData] = { artwork: Artwork _ SVArtwork.CreateColorArtwork[color, chalk]; sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, normal]; FOR sliceD: SliceDescriptor _ SVSelect.NextSliceDescriptor[sliceDescGen], SVSelect.NextSliceDescriptor[sliceDescGen] UNTIL sliceD=NIL DO SVAssembly.SetFillColor[sliceD.slice, sliceD.parts, artwork]; ENDLOOP; SVWindow.RestoreScreenAndInvariants[paintAction: $ObjectChangedInPlace, svData: svData, remake: none, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE]; }; AreaColorNone: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { AreaColorAux[NIL, svData]; }; AreaColorGray: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { whiteness: REAL _ NARROW[event.rest.first, REF REAL]^; color: Imager.Color _ ImagerColor.ColorFromGray[1.0 - whiteness]; AreaColorAux[color, svData]; }; AreaColorFromSelectedName: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { name: Rope.ROPE _ IF event.rest = NIL THEN ViewerTools.GetSelectionContents[] ELSE NARROW[event.rest.first]; color: Imager.Color _ ParseColorName[name, svData.feedback]; IF color#NIL THEN AreaColorAux[color, svData]; }; AreaColorFromSelectedRGB: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { name: Rope.ROPE _ IF event.rest = NIL THEN ViewerTools.GetSelectionContents[] ELSE NARROW[event.rest.first]; color: Imager.Color _ ImagerColor.ColorFromRGB[RGBFromRope[name ! RGBFromRopeError => GOTO SyntaxError]]; AreaColorAux[color, svData]; EXITS SyntaxError => {Feedback.Append[svData.feedback, "RGB Syntax is R: [0.0..1.0] G: [0.0..1.0] B: [0.0..1.0]", oneLiner]; Feedback.Blink[svData.feedback];}; }; RGBFromRopeError: SIGNAL = CODE; RGBFromRope: PROC [name: Rope.ROPE] RETURNS [rgb: ImagerColor.RGB] = { ENABLE IO.Error, IO.EndOfStream => GOTO RGBError; Check: PROC [x: REAL] = { IF x NOT IN [0.0..1.0] THEN SIGNAL RGBFromRopeError; }; rs: IO.STREAM _ IO.RIS[name]; IF Ascii.Upper[rs.GetChar[]]#'R THEN GOTO RGBError; IF rs.GetChar[]#': THEN GOTO RGBError; rgb.R _ rs.GetReal[]; [] _ rs.SkipWhitespace[]; IF Ascii.Upper[rs.GetChar[]]#'G THEN GOTO RGBError; IF rs.GetChar[]#': THEN GOTO RGBError; rgb.G _ rs.GetReal[]; [] _ rs.SkipWhitespace[]; IF Ascii.Upper[rs.GetChar[]]#'B THEN GOTO RGBError; IF rs.GetChar[]#': THEN GOTO RGBError; rgb.B _ rs.GetReal[]; Check[rgb.R]; Check[rgb.G]; Check[rgb.B]; EXITS RGBError => SIGNAL RGBFromRopeError; }; <<>> SetDefaultFillColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { sliceD: SliceDescriptor; sliceDescGen: SliceDescriptorGenerator _ SVSelect.SelectedSlices[svData.scene, normal]; IF sliceDescGen=NIL OR (sliceD _ SVSelect.NextSliceDescriptor[sliceDescGen])=NIL OR SVSelect.NextSliceDescriptor[sliceDescGen]#NIL THEN Feedback.Append[svData.feedback, "Select exactly one filled object for setting default fill color", oneLiner] ELSE { isProcessBlack: Rope.ROPE; red, green, blue: REAL; artwork: Artwork; artwork _ SVAssembly.GetFillColor[sliceD.slice, sliceD.parts]; IF artwork#NIL AND artwork.class = justColor THEN { color: Imager.ConstantColor _ NARROW[artwork.color]; [red,green,blue] _ GGCoreOps.ExtractRGB[color]; IF color = Imager.black THEN isProcessBlack _ " (process black)" ELSE IF ImagerColorPrivate.GrayFromColor[color]=1.0 THEN isProcessBlack _ " (CMY black)" ELSE isProcessBlack _ ""; Feedback.Append[ svData.feedback, IO.PutFR["Default Fill Color: R: %1.3f G: %1.3f B: %1.3f CNS: %g%g", [real[red]], [real[green]], [real[blue]], [rope[NamedColors.HSLToRope[ImagerColorFns.HSLFromRGB[[red,green,blue]]]]], [rope[isProcessBlack]] ], oneLiner]; } ELSE Feedback.Append[svData.feedback, "Default Fill Color: None", oneLiner]; svData.defaults.fillColor _ artwork; }; }; ShowDefaultFillColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = { isProcessBlack: Rope.ROPE; red, green, blue: REAL; color: Imager.ConstantColor _ NARROW[svData.defaults.fillColor.color]; IF color#NIL THEN { [red,green,blue] _ GGCoreOps.ExtractRGB[color]; IF color = Imager.black THEN isProcessBlack _ " (process black)" ELSE IF ImagerColorPrivate.GrayFromColor[color]=1.0 THEN isProcessBlack _ " (CMY black)" ELSE isProcessBlack _ ""; Feedback.Append[ svData.feedback, IO.PutFR["Default Fill Color: R: %1.3f G: %1.3f B: %1.3f CNS: %g%g", [real[red]], [real[green]], [real[blue]], [rope[NamedColors.HSLToRope[ImagerColorFns.HSLFromRGB[[red,green,blue]]]]], [rope[isProcessBlack]] ], oneLiner]; } ELSE Feedback.Append[svData.feedback, "Default Fill Color: None", oneLiner]; }; <<>> <