File: SVEditUserImplC.mesa
Last edited by Bier on July 7, 1987 3:28:36 pm PDT
Copyright © 1984 by Xerox Corporation. All rights reserved.
Author: Eric Bier
Contents: All of the procedures called by SVEditTool when menus and buttons are pressed (part 3)
DIRECTORY
CoordSys, Feedback, FS, Imager, IO, Labels, Matrix3d, Menus, Rope, SlackProcess, SV2d, SV3d, SVAssembly, SVBasicTypes, SVBoundBox, SVCaret, SVEditUser, SVEditUserB, SVGraphics, SVHalfSpaces, SVInterfaceTypes, SVMasterObject, SVMasterObjectTypes, SVModelTypes, SVPolygon2d, SVRefresh, SVScene, SVSceneTypes, SVScratchpadUser, SVSelect, SVSelections, SVTransforms, SVViewersOnScene, SVViewerTools, SweepGeometry, TiogaMenuOps, ViewerClasses, ViewerTools;
SVEditUserImplC: CEDAR PROGRAM
IMPORTS CoordSys, Feedback, FS, IO, Labels, Matrix3d, Rope, SlackProcess, SVAssembly, SVBoundBox, SVCaret, SVEditUser, SVPolygon2d, SVRefresh, SVScene, SVScratchpadUser, SVSelect, SVSelections, SVTransforms, SVViewersOnScene, SVViewerTools, SweepGeometry, TiogaMenuOps, ViewerTools
EXPORTS SVEditUser, SVEditUserB =
BEGIN
Slice: TYPE = REF SliceObj;
SliceObj: TYPE = SVSceneTypes.SliceObj;
SliceList: TYPE = SVSceneTypes.SliceList;
BoundBox: TYPE = SVBasicTypes.BoundBox;
Camera: TYPE = SVModelTypes.Camera;
Color: TYPE = Imager.Color;
CoordSystem: TYPE = SVModelTypes.CoordSystem;
EditToolData: TYPE = SVInterfaceTypes.EditToolData;
LinearMesh: TYPE = SweepGeometry.LinearMesh;
MasterObject: TYPE = SVSceneTypes.MasterObject;
Matrix4by4: TYPE = SV3d.Matrix4by4;
MouseButton: TYPE = Menus.MouseButton;
Path: TYPE = SV2d.Path;
Point3d: TYPE = SV3d.Point3d;
Polygon: TYPE = SV2d.Polygon;
PointSetOp: TYPE = SVSceneTypes.PointSetOp;
RevoluteMesh: TYPE = SweepGeometry.RevoluteMesh;
Scene: TYPE = SVSceneTypes.Scene;
ScratchpadData: TYPE = SVInterfaceTypes.ScratchpadData;
ScratchViewerData: TYPE = SVInterfaceTypes.ScratchViewerData;
Selection: TYPE = SVInterfaceTypes.Selection;
SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator;
Shape: TYPE = SVSceneTypes.Shape;
SliceDescriptorGenerator: TYPE = SVSceneTypes.SliceDescriptorGenerator;
Vector3d: TYPE = SV3d.Vector3d;
Viewer: TYPE = ViewerClasses.Viewer;
ViewerCell: TYPE = REF ViewerCellObj;
ViewerCellObj: TYPE = SVInterfaceTypes.ViewerCellObj;
SVData: TYPE = SVInterfaceTypes.SVData;
Basic Shapes
HalfSpaceRec: TYPE = SVHalfSpaces.HalfSpaceRec;
SphereRec: TYPE = SVMasterObjectTypes.SphereRec;
BlockData: TYPE = SVMasterObjectTypes.BlockData;
CylinderRec: TYPE = SVMasterObjectTypes.CylinderRec;
ConeRec: TYPE = SVMasterObjectTypes.ConeRec;
TorusRec: TYPE = SVMasterObjectTypes.TorusRec;
GLOBAL VARIABLES
globalOpIndex: NAT ← 1;
globalOpCount: NAT = 3;
globalOpArray: ARRAY[1..globalOpCount] OF Rope.ROPE
["union", "intersection", "difference"];
globalIsColor: BOOLFALSE;
Text Input Section
PlaneButtonAux: PRIVATE PROC [planeName: Rope.ROPE, editToolData: EditToolData] = {
Use planeName to coordsys-select. Create a plane-selection of this assembly.
currentScene: Scene ← editToolData.sceneSection.currentScene;
svData: SVData ← editToolData.currentSVData;
planeSel: Selection;
planeAssem: Slice;
success: BOOL;
[planeAssem, ----, success] ← SVScene.FindAssemblyFromName[planeName, currentScene];
IF NOT success THEN RETURN;
planeSel ← SVSelections.CreatePlaneSelection[planeAssem, svData];
SVSelections.PushPlane[planeSel];
SVViewersOnScene.PaintSceneAllViewers[$DrawPlane, editToolData, currentScene];
};
SourceButtonAux: PRIVATE PROC [sourceName: Rope.ROPE, editToolData: EditToolData] = {
Use sourceName to coordsys-select. Create a source-selection of this assembly.
currentScene: Scene ← editToolData.sceneSection.currentScene;
svData: SVData ← editToolData.currentSVData;
sourceSel: Selection;
source: Slice;
success: BOOL;
IF Rope.Equal[sourceName, "background", TRUE] THEN {
source ← NEW[SliceObj ← [
name: "background",
coordSys: currentScene.coordSysRoot,
shape: NIL,
normalSelectedParts: NIL,
hotSelectedParts: NIL,
activeSelectedParts: NIL,
onOverlay: FALSE,
mark: FALSE,
artwork: NIL,
showAs: normal,
isTool: FALSE,
toolMasterObject: NIL,
sittingOn: NIL
]];
success ← TRUE;
}
ELSE [source, ----, success] ← SVScene.FindAssemblyFromName[sourceName, currentScene];
IF NOT success THEN RETURN;
sourceSel ← SVSelections.CreateCoordSysMovee[source, svData];
SVSelections.PushMovee[sourceSel];
SVViewersOnScene.PaintSceneAllViewers[$SelectionChanged, editToolData, currentScene];
};
TargetButtonAux: PRIVATE PROC [targetName: Rope.ROPE, editToolData: EditToolData] = {
Use targetName to coordsys-select. Create a target-selection of this assembly.
currentScene: Scene ← editToolData.sceneSection.currentScene;
svData: SVData ← editToolData.currentSVData;
targetSel: Selection;
target: Slice;
success: BOOL;
IF Rope.Equal[targetName, "WORLD", TRUE] THEN {
target ← NEW[SliceObj ← [
name: "WORLD",
coordSys: currentScene.coordSysRoot,
shape: NIL,
normalSelectedParts: NIL,
hotSelectedParts: NIL,
activeSelectedParts: NIL,
onOverlay: FALSE,
mark: FALSE,
artwork: NIL,
showAs: normal,
isTool: FALSE,
toolMasterObject: NIL,
sittingOn: NIL
]];
success ← TRUE;
}
ELSE [target, ----, success] ← SVScene.FindAssemblyFromName[targetName, currentScene];
IF NOT success THEN RETURN;
targetSel ← SVSelections.CreateCoordSysTarget[target, svData];
SVSelections.PushTarget[targetSel];
SVViewersOnScene.PaintSceneAllViewers[$SelectionChanged, editToolData, currentScene];
};
ParentButtonAux: PRIVATE PROC [parentName: Rope.ROPE, editToolData: EditToolData] = {
Stuff parentName into the Parent slot.
currentScene: Scene ← editToolData.sceneSection.currentScene;
success: BOOL;
[----, ----, success] ← SVScene.FindAssemblyFromName[parentName, currentScene];
IF NOT success THEN RETURN;
ViewerTools.SetContents[editToolData.sceneSection.parent, parentName];
};
SkitterSourceButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Use the text in the skitter area as the name of an assembly to coordsys-select. Create a source-selection of this assembly.
sourceName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
sourceName ← ViewerTools.GetContents[editToolData.sceneSection.current];
SourceButtonAux[sourceName, editToolData];
};
SkitterTargetButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
targetName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
targetName ← ViewerTools.GetContents[editToolData.sceneSection.current];
TargetButtonAux[targetName, editToolData];
};
SkitterParentButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Stuff the text next to Skitter: into the Parent slot.
editToolData: EditToolData ← svData.editToolData;
parentName: Rope.ROPE;
parentName ← ViewerTools.GetContents[editToolData.sceneSection.current];
ParentButtonAux[parentName, editToolData];
};
Text1PromptButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
ViewerTools.SetSelection[editToolData.sceneSection.text1];
};
Text1SourceButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
sourceName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
sourceName ← ViewerTools.GetContents[editToolData.sceneSection.text1];
SourceButtonAux[sourceName, editToolData];
};
Text1TargetButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
targetName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
targetName ← ViewerTools.GetContents[editToolData.sceneSection.text1];
TargetButtonAux[targetName, editToolData];
};
Text1ParentButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Stuff the text next to Text1: into the Parent slot.
editToolData: EditToolData ← svData.editToolData;
parentName: Rope.ROPE;
parentName ← ViewerTools.GetContents[editToolData.sceneSection.text1];
ParentButtonAux[parentName, editToolData];
};
SelectedTextPlaneButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
planeName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
planeName ← ViewerTools.GetSelectionContents[];
PlaneButtonAux[planeName, editToolData];
};
SelectedTextSourceButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
sourceName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
sourceName ← ViewerTools.GetSelectionContents[];
SourceButtonAux[sourceName, editToolData];
};
SelectedTextTargetButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
targetName: Rope.ROPE;
editToolData: EditToolData ← svData.editToolData;
targetName ← ViewerTools.GetSelectionContents[];
TargetButtonAux[targetName, editToolData];
};
SelectedTextParentButton: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Stuff the text of the current selection into the Parent slot.
editToolData: EditToolData ← svData.editToolData;
parentName: Rope.ROPE;
parentName ← ViewerTools.GetSelectionContents[];
ParentButtonAux[parentName, editToolData];
};
Prompts which cycle through possibilities
SelectOp: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
globalOpIndex ← IF globalOpIndex = globalOpCount THEN 1 ELSE globalOpIndex + 1;
Labels.Set[editToolData.sceneSection.opLabel, globalOpArray[globalOpIndex]];
SELECT globalOpArray[globalOpIndex] FROM
"union" => editToolData.sceneSection.op ← union;
"intersection" => editToolData.sceneSection.op ← intersection;
"difference" => editToolData.sceneSection.op ← difference;
ENDCASE => ERROR;
};
IsColor: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
truthRope: Rope.ROPE;
globalIsColor ← NOT globalIsColor;
truthRope ← IF globalIsColor THEN "TRUE" ELSE "FALSE";
Labels.Set[editToolData.artworkSection.isColor, truthRope];
};
Command Buttons
First: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Make sure that the assembly named in "Slice: " is the first element in the SliceList of its super assembly (useful when csg op = "difference" since the result of difference is that of the first element minus all of the rest.
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
assembly, superA: Slice;
found: BOOL;
namePresent: BOOLFALSE;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[assembly, superA, found] ← SVScene.FindAssemblyFromName[assembly.name, scene];
IF NOT found THEN RETURN;
SVScene.MoveToFrontOfAssembly[assembly, superA, scene];
SVViewersOnScene.SceneNewVersion[editToolData.currentSVData];
}; -- end of First
DrawCS: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
find the assembly mentioned by the edittool and draw its coordinate system.
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
assembly: Slice;
cs: CoordSystem;
success: BOOL;
viewerCell: ViewerCell;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
cs ← assembly.coordSys;
[viewerCell, success] ← SVViewersOnScene.FindSceneInAllViewers[scene, editToolData.allViewers];
IF NOT success THEN ERROR;
Draw the first viewer if there is one.
IF viewerCell.viewersOnScene = NIL THEN RETURN;
svData ← NARROW[viewerCell.viewersOnScene.data];
SVEvent.DrawOneCSInViewer[svData, cs];
draw the rest (remember they are linked in a ring)
IF viewerCell.viewersOnScene.link = NIL THEN RETURN;
FOR list: Viewer ← viewerCell.viewersOnScene.link, list.link
UNTIL list = viewerCell.viewersOnScene DO
svData ← NARROW[list.data];
SVEvent.DrawOneCSInViewer[svData, cs];
ENDLOOP;
};
Delete: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
arg: ATOM ← NARROW[event.rest.first];
IF arg=$Undo THEN {
Feedback.AppendRaw[$Solidviews, "Can't undo Delete. Sorry.", oneLiner];
Feedback.BlinkRaw[$Solidviews];
RETURN;
};
DeleteInternal[editToolData];
};
DeleteInternal: PUBLIC PROC [editToolData: EditToolData] = {
found: BOOLTRUE;
svData: SVData ← editToolData.currentSVData;
scene: Scene ← svData.scene;
bBoxOfSelected: BoundBox;
camera: Camera ← svData.camera;
SVSelections.ClearMoveeStack[editToolData];
SVSelections.ClearTargetStack[editToolData];
bBoxOfSelected ← SVBoundBox.BoundBoxOfSelected[scene, camera, normal];
IF bBoxOfSelected=NIL THEN RETURN; -- nothing selected
svData.refresh.startBoundBox^ ← SVScene.DeleteAllSelected[scene, camera]^;
SVCaret.NoAttractor[editToolData.skitter];
SVViewersOnScene.PaintSceneAllViewers[paintAction: $PaintEntireScene, editToolData: editToolData, scene: scene, remake: triggerBag, backgndOK: FALSE, edited: TRUE, okToClearFeedback: TRUE];
};
SetOp: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
the name in the assembly slot should refer to an already existing Composite Slice. Make its SVRay pointSetOp equal to the op shown next to "Op:". Error if Slice is a Primitive Slice.
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
pointSetOp: PointSetOp ← editToolData.sceneSection.op;
compAssembly: Slice;
namePresent: BOOLFALSE;
arg: ATOM ← NARROW[event.rest.first];
IF arg=$Undo THEN {
Feedback.AppendRaw[$Solidviews, "Can't undo SetOp!", oneLiner];
Feedback.BlinkRaw[$Solidviews];
RETURN};
compAssembly ← SVSelections.PopMoveeCoincident[];
IF compAssembly = NIL THEN RETURN;
WITH compAssembly.shape SELECT FROM
shape: Shape => {
Feedback.PutFRaw[$Solidviews, oneLiner, "Can't add op to primitive assembly %g.", [rope[compAssembly.name]]];
Feedback.BlinkRaw[$Solidviews];
RETURN};
al: SliceList => al.pointSetOp ← pointSetOp;
ENDCASE => ERROR;
SVViewersOnScene.SceneNewVersion[editToolData.currentSVData];
}; -- end of SetOp
Help: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
fullName: Rope.ROPE;
wdir: Rope.ROPE;
success: BOOL ← TRUE;
wdir ← editToolData.originalWorkingDirectory;
[fullName,,] ← FS.ExpandName["SVHelpFile.tioga", wdir
! FS.Error => IF error.group = user THEN {
success ← FALSE;
CONTINUE;
}
];
IF NOT success THEN RETURN;
[] ← TiogaMenuOps.Open[fullName];
};
SetColorMap: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
};
BWMap: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
};
Revive: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
currentSVData: SVData ← editToolData.currentSVData;
SVRefresh.MoveOverlayToBackground[currentSVData];
SlackProcess.Restart[currentSVData.slackHandle];
};
RotX: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
degrees: REAL ← SVViewerTools.GetReal[editToolData.transformSection.degrees, 0];
arg: ATOMNARROW[event.rest.first];
IF arg=$Undo THEN degrees ← -degrees;
RotAxis[editToolData, degrees, 1];
};
RotY: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
degrees: REAL ← SVViewerTools.GetReal[editToolData.transformSection.degrees, 0];
arg: ATOMNARROW[event.rest.first];
IF arg=$Undo THEN degrees ← -degrees;
RotAxis[editToolData, degrees, 2];
};
RotZ: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
degrees: REAL ← SVViewerTools.GetReal[editToolData.transformSection.degrees, 0];
arg: ATOMNARROW[event.rest.first];
IF arg=$Undo THEN degrees ← -degrees;
RotAxis[editToolData, degrees, 3];
};
RotAxis: PUBLIC PROC [editToolData: EditToolData, degrees: REAL, axis: [1..3]] = {
scene: Scene ← editToolData.sceneSection.currentScene;
targetCS: CoordSystem;
anchorWorld, rotation: Matrix4by4;
targetCSspecified: BOOLTRUE;
sliceDescGen: SliceDescriptorGenerator;
success: BOOLTRUE;
targetCS ← SVSelections.TopTargetCoinCoordSys[];
IF targetCS = NIL THEN targetCSspecified ← FALSE;
IF NOT SVCaret.Exists[scene.anchor] THEN targetCSspecified ← FALSE
ELSE {
anchorWorld ← SVCaret.GetPosition[scene.anchor];
};
rotation ← Matrix3d.MakeRotateMat[axis, degrees];
sliceDescGen ← SVSelect.SelectedSlices[scene, normal];
FOR coin: Slice ← SVSelect.NextSlice[sliceDescGen], SVSelect.NextSlice[sliceDescGen] UNTIL coin = NIL DO
IF NOT targetCSspecified THEN anchorWorld ← CoordSys.WRTWorld[coin.coordSys];
SVAssembly.IncTransfMatrix[coin, anchorWorld, rotation];
ENDLOOP;
SVViewersOnScene.PaintSceneAllViewers[paintAction: $PaintEntireScene, editToolData: editToolData, scene: scene, edited: TRUE];
};
Trans: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
x, y, z: REAL;
targetCS: CoordSystem;
anchorWorld, translation: Matrix4by4;
targetCSspecified: BOOLTRUE;
sliceDescGen: SliceDescriptorGenerator;
success: BOOLTRUE;
vec: Vector3d;
arg: ATOMNARROW[event.rest.first];
[x, y, z] ← SVViewerTools.GetThreeReals[editToolData.transformSection.transXYZ];
IF arg=$Undo THEN {x ← -x; y ← -y; z ← -z};
vec ← [x, y, z];
targetCS ← SVSelections.TopTargetCoinCoordSys[];
IF targetCS = NIL THEN targetCSspecifiedFALSE;
IF NOT SVCaret.Exists[scene.anchor] THEN targetCSspecified ← FALSE
ELSE {
anchorWorld ← SVCaret.GetPosition[scene.anchor];
};
translation ← Matrix3d.MakeTranslateMat[vec[1], vec[2], vec[3]];
sliceDescGen ← SVSelect.SelectedSlices[scene, normal];
FOR coin: Slice ← SVSelect.NextSlice[sliceDescGen], SVSelect.NextSlice[sliceDescGen] UNTIL coin = NIL DO
IF NOT targetCSspecified THEN anchorWorld ← CoordSys.WRTWorld[coin.coordSys];
SVAssembly.IncTransfMatrix[coin, anchorWorld, translation];
ENDLOOP;
SVViewersOnScene.PaintSceneAllViewers[paintAction: $PaintEntireScene, editToolData: editToolData, scene: scene, edited: TRUE];
};
EvenScale: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
targetCS: CoordSystem;
anchorWorld, scaleMat: Matrix4by4;
scalar: REAL;
targetCSspecified: BOOLTRUE;
sliceDescGen: SliceDescriptorGenerator;
success: BOOLTRUE;
arg: ATOMNARROW[event.rest.first];
BEGIN
scalar ← SVViewerTools.GetReal[editToolData.transformSection.scalar, 0];
IF scalar = 0 THEN GOTO ScaleByZero;
IF arg=$Undo THEN {scalar ← 1/scalar};
targetCS ← SVSelections.TopTargetCoinCoordSys[];
IF targetCS = NIL THEN targetCSspecified ← FALSE;
IF NOT SVCaret.Exists[scene.anchor] THEN targetCSspecified ← FALSE
ELSE {
anchorWorld ← SVCaret.GetPosition[scene.anchor];
};
scaleMat ← Matrix3d.MakeScaleMat[scalar, scalar, scalar];
sliceDescGen ← SVSelect.SelectedSlices[scene, normal];
FOR coin: Slice ← SVSelect.NextSlice[sliceDescGen], SVSelect.NextSlice[sliceDescGen] UNTIL coin = NIL DO
IF NOT targetCSspecified THEN anchorWorld ← CoordSys.WRTWorld[coin.coordSys];
SVAssembly.IncTransfMatrix[coin, anchorWorld, scaleMat];
ENDLOOP;
SVViewersOnScene.PaintSceneAllViewers[paintAction: $PaintEntireScene, editToolData: editToolData, scene: scene, edited: TRUE];
EXITS
ScaleByZero => {
Feedback.AppendRaw[$Solidviews, "Can't scale by 0", oneLiner];
Feedback.BlinkRaw[$Solidviews];
};
END;
};
ScalePrimitive: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
x, y, z: REAL;
sliceDescGen: SliceDescriptorGenerator;
bad: Slice;
success: BOOLTRUE;
arg: ATOM ← NARROW[event.rest.first];
BEGIN
[x, y, z] ← SVViewerTools.GetThreeReals[editToolData.transformSection.scaleXYZ];
IF x = 0 OR y = 0 OR z = 0 THEN GOTO ScaleByZero;
IF arg=$Undo THEN {x ← 1/x; y ← 1/y; z ← 1/z};
sliceDescGen ← SVSelect.SelectedSlices[scene, normal];
FOR coin: Slice ← SVSelect.NextSlice[sliceDescGen], SVSelect.NextSlice[sliceDescGen] UNTIL coin = NIL DO
IF NOT ISTYPE[coin.shape, Shape] THEN {bad ← coin; GOTO ScalePrimitive};
SVTransforms.ScalePrimitives[coin, x, y, z];
ENDLOOP;
SVViewersOnScene.PaintSceneAllViewers[paintAction: $PaintEntireScene, editToolData: editToolData, scene: scene, edited: TRUE];
EXITS
ScaleByZero => {
Feedback.AppendRaw[$Solidviews, "Can't scale by 0", oneLiner];
Feedback.BlinkRaw[$Solidviews];
};
ScalePrimitive => {
errorRope ← IO.PutFR["Can't ScalePrimitive! a cluster assembly [%g]",[rope[bad.name]]];
Feedback.AppendRaw[$Solidviews, errorRope, oneLiner];
Feedback.BlinkRaw[$Solidviews];
};
END;
};
Edit: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Find out if the current object is a sweep shape. If so, extract its path and feed to the scratchpad. Otherwise complain in Feedback.
editToolData: EditToolData ← svData.editToolData;
scratchpad: Viewer ← editToolData.scratchpad;
scratchpadData: ScratchpadData ← NARROW[scratchpad.data];
scratchViewerData: ScratchViewerData ← scratchpadData.scratchViewerData;
scene: Scene ← editToolData.sceneSection.currentScene;
mo: MasterObject;
shape: Shape;
scalars: Vector3d;
path: Path;
poly: Polygon;
moClassName: Rope.ROPE;
assembly: Slice;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
Feedback.AppendRaw[$Solidviews, "Cannot Edit Composite Slice", oneLiner];
Feedback.BlinkRaw[$Solidviews];
RETURN};
shape ← NARROW[assembly.shape];
mo ← shape.mo;
scalars ← CoordSys.GetScalars[shape.coordSys];
moClassName ← mo.class.name;
SELECT TRUE FROM
Rope.Equal[moClassName, "revoluteSweep"] => {
path ← SweepGeometry.GetRevolutePath[NARROW[mo.lineBody, RevoluteMesh]];
SVScratchpadUser.Edit[path, revo, scratchViewerData];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, scalars[1], scalars[2], scalars[3]];
};
Rope.Equal[moClassName, "linearSweep"] => {
linMesh: LinearMesh ← NARROW[mo.lineBody];
depth: REAL;
poly ← SweepGeometry.GetLinearPoly[linMesh];
path ← SVPolygon2d.PolygonToPath[poly];
SVScratchpadUser.Edit[path, lin, scratchViewerData];
depth ← linMesh.array[1][1][3]*2;
SVViewerTools.SetReal[editToolData.linSection.depth, depth];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, scalars[1], scalars[2], scalars[3]];
};
Rope.Equal[moClassName, "sphere"] => {
A sphere may actually be an oblate spheroid if the scalars are uneven. If they are even, I will will stuff the radius. Otherwise, I will set radius = 1 and stuff the scalars in the scaling part of the transform section. **** This should also stuff the name of the sphere's parent in "With Respect To:".
radius: REAL;
sphereRec: SphereRec ← NARROW[mo.mainBody];
radius ← sphereRec.radius;
IF scalars[1] = scalars[2] AND scalars[2] = scalars[3]
THEN {-- stuff the radius and 1's into the scalars
SVViewerTools.SetReal[editToolData.sphereSection.radius, scalars[1]*radius];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, 1,1,1];
}
ELSE {-- radius = 1; write scalars
SVViewerTools.SetReal[editToolData.sphereSection.radius, 1];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, scalars[1]*radius, scalars[2]*radius, scalars[3]*radius];
};
};
Rope.Equal[moClassName, "block"] => {
bx, by, bz: REAL;
blockRec: BlockData ← NARROW[mo.mainBody];
bx ← blockRec.box.hiX - blockRec.box.loX;
by ← blockRec.box.hiY - blockRec.box.loY;
bz ← blockRec.box.hiZ - blockRec.box.loZ;
SVViewerTools.SetThreeReals[editToolData.blockSection.xyz, bx*scalars[1], by*scalars[2], bz*scalars[3]];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, 1,1,1];
};
Rope.Equal[moClassName, "cylinder"] => {
if sx = sz then stuff radius and height. Otherwise using scaling blank to list all scalars
radius, height: REAL;
cylinderRec: CylinderRec ← NARROW[mo.mainBody];
radius ← cylinderRec.radius;
height ← cylinderRec.height;-- dimensions of the master object
IF scalars[1] = scalars[3] THEN {
SVViewerTools.SetReal[editToolData.cylinderSection.radius, radius*scalars[1]];
SVViewerTools.SetReal[editToolData.cylinderSection.height, height*scalars[2]];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, 1,1,1];
}
ELSE {
SVViewerTools.SetReal[editToolData.cylinderSection.radius, 1];
SVViewerTools.SetReal[editToolData.cylinderSection.height, 1];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, scalars[1]*radius, scalars[2]*height, scalars[3]*radius];
};
};
Rope.Equal[moClassName, "cone"] => {
similar to cylinder
radius, height: REAL;
coneRec: ConeRec ← NARROW[mo.mainBody];
radius ← coneRec.radius;
height ← coneRec.height;-- dimensions of the master object
IF scalars[1] = scalars[3] THEN {
SVViewerTools.SetReal[editToolData.coneSection.radius, radius*scalars[1]];
SVViewerTools.SetReal[editToolData.coneSection.height, height*scalars[2]];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, 1,1,1];
}
ELSE {
SVViewerTools.SetReal[editToolData.coneSection.radius, 1];
SVViewerTools.SetReal[editToolData.coneSection.height, 1];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, scalars[1]*radius, scalars[2]*height, scalars[3]*radius];
};
};
Rope.Equal[moClassName, "torus"] => {
in the case of the torus, we write the current scalars AND take the radius data directly from the torus record (master object)
bigRadius, sectionRadius: REAL;
torusRec: TorusRec ← NARROW[mo.mainBody];
bigRadius ← torusRec.bigRadius;
sectionRadius ← torusRec.sectionRadius;
SVViewerTools.SetReal[editToolData.torusSection.bigRadius, bigRadius];
SVViewerTools.SetReal[editToolData.torusSection.sectionRadius, sectionRadius];
SVViewerTools.SetThreeReals[editToolData.transformSection.scaleXYZ, scalars[1], scalars[2], scalars[3]];
};
ENDCASE => {
Feedback.AppendRaw[$Solidviews, Rope.Concat["I don't know how to edit ", moClassName], oneLiner];
Feedback.BlinkRaw[$Solidviews];
};
}; -- end of Edit
AddComposite: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
Use the name in the assembly slot to name this new composite. It is a subassembly of the assembly named in "WithRespectTo"; It has no sub-assemblies to begin with. Add * will now add objects to the assembly named in "WithRespectTo".
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
pointSetOp: PointSetOp ← editToolData.sceneSection.op;
compName: Rope.ROPE;
newAssembly, superAssembly: Slice;
success: BOOL;
addSucceeds: BOOLTRUE;
compName ← ViewerTools.GetContents[editToolData.sceneSection.new];
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, addSucceeds] ← SVAssembly.CreateCluster[compName, pointSetOp, scene];
IF NOT addSucceeds THEN RETURN;
addSucceeds ← SVAssembly.AddCluster[newAssembly, superAssembly, Matrix3d.Identity[], scene];
IF NOT addSucceeds THEN RETURN;
SVViewersOnScene.SceneNewVersion[editToolData.currentSVData];
}; -- end of AddComposite
SetAmbient: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
color: Color;
success: BOOLEAN;
[color, success] ← SVViewerTools.GetColor[editToolData.lightSection.color];
IF NOT success THEN RETURN;
IF NOT scene.lightSources.first.type = ambient THEN ERROR;
scene.lightSources.first.color ← color;
SVViewersOnScene.SceneNewVersion[editToolData.currentSVData];
SVViewersOnScene.PaintSceneAllViewers[$PaintEntireScene, editToolData, scene];
};
GetAmbient: PUBLIC PROC [event: LIST OF REF ANY, svData: SVData] = {
editToolData: EditToolData ← svData.editToolData;
scene: Scene ← editToolData.sceneSection.currentScene;
color: Color;
IF NOT scene.lightSources.first.type = ambient THEN ERROR;
color ← scene.lightSources.first.color;
SVViewerTools.SetColor[editToolData.lightSection.color, color];
};
END.