File: SVEditUserImplB.mesa
Created in October 1982
Copyright © 1984 by Xerox Corporation. All rights reserved.
Last edited by Bier on August 1, 1985 3:24:03 pm PDT
Contents: All of the procedures called by SVEditTool when menus and buttons are pressed
DIRECTORY
BasicObject3d,
CoordSys,
DisplayList3d,
Imager,
IO,
Matrix3d,
Menus,
Rope,
Scratchpad2d,
SV2d,
SV3d,
SVEditUser,
SVError,
SVHalfSpaces,
SVInterfaceTypes,
SVModelTypes,
SVSceneTypes,
SVSelections,
SVPolygon2d,
SVViewerTools,
SVViewerUser,
SweepGeometry,
ViewerClasses,
ViewerTools;
SVEditUserImplB: CEDAR PROGRAM
IMPORTS BasicObject3d, CoordSys, DisplayList3d, IO, Matrix3d, Rope, SweepGeometry, Scratchpad2d, SVEditUser, SVError, SVPolygon2d, SVSelections, SVViewerTools, SVViewerUser, ViewerTools
EXPORTS SVEditUser =
BEGIN
Assembly: TYPE = SVSceneTypes.Assembly;
AssemblyList: TYPE = SVSceneTypes.AssemblyList;
AssemblyGenerator: TYPE = DisplayList3d.AssemblyGenerator;
Color: TYPE = Imager.Color;
EditToolData: TYPE = SVInterfaceTypes.EditToolData;
LightSource: TYPE = SVModelTypes.LightSource;
LinearMesh: TYPE = SweepGeometry.LinearMesh;
MasterObject: TYPE = SVSceneTypes.MasterObject;
Matrix4by4: TYPE = SV3d.Matrix4by4;
MouseButton: TYPE = Menus.MouseButton;
NameAlreadyPresent: SIGNAL = DisplayList3d.NameAlreadyPresent;
Point3d: TYPE = SV3d.Point3d;
Polygon: TYPE = SV2d.Polygon;
RevoluteMesh: TYPE = SweepGeometry.RevoluteMesh;
Path: TYPE = SV2d.Path;
Scene: TYPE = SVSceneTypes.Scene;
SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator;
Shape: TYPE = SVSceneTypes.Shape;
Viewer: TYPE = ViewerClasses.Viewer;
ViewerCell: TYPE = SVInterfaceTypes.ViewerCell;
ViewerToolData: TYPE = SVInterfaceTypes.ViewerToolData;
Basic Shapes
HalfSpaceRec: TYPE = SVHalfSpaces.HalfSpaceRec;
SphereRec: TYPE = BasicObject3d.SphereRec;
BlockRec: TYPE = BasicObject3d.BlockRec;
CylinderRec: TYPE = BasicObject3d.CylinderRec;
ConeRec: TYPE = BasicObject3d.ConeRec;
TorusRec: TYPE = BasicObject3d.TorusRec;
AddHalfSpace: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
If mouseButton = red or yellow, then make sure this assembly name is unique and add a new sphere by this name. if mouseButton = blue, then find the old assembly by this name. Make sure it is a primitive assembly. Let it refer to halfSpace as its master object and use the new scalar values.
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
halfSpaceName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
halfSpaceMO: MasterObject;
moFound: BOOL;
halfSpaceRec: HalfSpaceRec;
[halfSpaceMO, moFound] ← DisplayList3d.FindObjectFromName["halfSpace", scene];
IF NOT moFound THEN ERROR;
halfSpaceRec ← NARROW[halfSpaceMO.mainBody];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[halfSpaceName, "halfSpace", [1, 1, 1], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE {-- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["halfSpace", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't replace cluster assembly [%g] with a halfSpace.",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [1, 1, 1]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddHalfSpace
AddSteiner: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
If mouseButton = red or yellow, then make sure this assembly name is unique and add a new sphere by this name. if mouseButton = blue, then find the old assembly by this name. Make sure it is a primitive assembly. Let it refer to halfSpace as its master object and use the new scalar values.
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
steinerName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
steinerMO: MasterObject;
moFound: BOOL;
[steinerMO, moFound] ← DisplayList3d.FindObjectFromName["steiner", scene];
IF NOT moFound THEN ERROR;
halfSpaceRec ← NARROW[halfSpaceMO.mainBody];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[steinerName, "steiner", [30, 30, 30], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE {-- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["steiner", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't replace cluster assembly [%g] with a steiner.",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [30, 30, 30]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddSteiner
AddExtra1: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
The Arnon Sphere.
If mouseButton = red or yellow, then make sure this assembly name is unique and add a new sphere by this name. if mouseButton = blue, then find the old assembly by this name. Make sure it is a primitive assembly. Let it refer to halfSpace as its master object and use the new scalar values.
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
sphereName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
sphereMO: MasterObject;
moFound: BOOL;
[sphereMO, moFound] ← DisplayList3d.FindObjectFromName["arnonSphere", scene];
IF NOT moFound THEN ERROR;
halfSpaceRec ← NARROW[halfSpaceMO.mainBody];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[sphereName, "arnonSphere", [30, 30, 30], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE {-- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["arnonSphere", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't replace cluster assembly [%g] with a sphere.",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [30, 30, 30]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddExtra1
AddExtra2: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
The Arnon Sphere.
If mouseButton = red or yellow, then make sure this assembly name is unique and add a new sphere by this name. if mouseButton = blue, then find the old assembly by this name. Make sure it is a primitive assembly. Let it refer to halfSpace as its master object and use the new scalar values.
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
catastropheName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
catastropheMO: MasterObject;
moFound: BOOL;
[catastropheMO, moFound] ← DisplayList3d.FindObjectFromName["catastrophe", scene];
IF NOT moFound THEN ERROR;
halfSpaceRec ← NARROW[halfSpaceMO.mainBody];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[catastropheName, "catastrophe", [10, 10, 10], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE {-- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["catastrophe", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't replace cluster assembly [%g] with a sphere.",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [10, 10, 10]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddExtra2
AddExtra3: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = {};
AddExtra4: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = {};
AddSphere: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
If mouseButton = red or yellow, then make sure this assembly name is unique and add a new sphere by this name. if mouseButton = blue, then find the old assembly by this name. Make sure it is a primitive assembly. Let it refer to sphere as its master object and use the new scalar values.
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
sphereName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
radius: REAL ← SVViewerTools.GetReal[editToolData.sphereSection.radius, 200];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
sphereMO: MasterObject;
moFound: BOOL;
sphereRec: SphereRec;
moRadius: REAL;
[sphereMO, moFound] ← DisplayList3d.FindObjectFromName["sphere", scene];
IF NOT moFound THEN ERROR;
sphereRec ← NARROW[sphereMO.mainBody];
moRadius ← sphereRec.radius;
radius ← radius/moRadius;
We need to know the size of the master object in order to know what scalars to use to achieve a sphere of the size requested by the user.
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[sphereName, "sphere", [radius, radius, radius], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE {-- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["sphere", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitue a sphere for a cluster assembly [%g]",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [radius, radius, radius]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddSphere
AddBlock: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
x, y, z: REAL;
blockName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
blockMO: MasterObject;
moFound: BOOL;
blockRec: BlockRec;
[blockMO, moFound] ← DisplayList3d.FindObjectFromName["block", scene];
IF NOT moFound THEN ERROR;
blockRec ← NARROW[blockMO.mainBody];
We need to know the size of the master object in order to know what scalars to use to achieve a block of the size requested by the user.
[x, y, z] ← SVViewerTools.GetThreeReals[editToolData.blockSection.xyz];
x ← x/blockRec.x; y ← y/blockRec.y; z ← z/blockRec.z;
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ← DisplayList3d.CreateAndAddPrimitiveAssembly[blockName, "block", [x, y, z], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE { -- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["block", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitue a block for a cluster assembly [%g]",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [x, y, z]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddBlock
AddCyl: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
cylName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
radius: REAL ← SVViewerTools.GetReal[editToolData.cylinderSection.radius, 200];
height: REAL ← SVViewerTools.GetReal[editToolData.cylinderSection.height, 300];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
cylMO: MasterObject;
moFound: BOOL;
cylinderRec: CylinderRec;
[cylMO, moFound] ← DisplayList3d.FindObjectFromName["cylinder", scene];
IF NOT moFound THEN ERROR;
cylinderRec ← NARROW[cylMO.mainBody];
We need to know the size of the master object in order to know what scalars to use to achieve a cylinder of the size requested by the user.
radius ← radius/cylinderRec.radius; height ← height/cylinderRec.height;
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[cylName, "cylinder", [radius, height, radius], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE { -- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["cylinder", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitute a cylinder for a cluster assembly [%g]",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [radius, height, radius]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddCyl
AddCone: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
coneName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
radius: REAL ← SVViewerTools.GetReal[editToolData.coneSection.radius, 200];
height: REAL ← SVViewerTools.GetReal[editToolData.coneSection.height, 300];
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
coneMO: MasterObject;
moFound: BOOL;
coneRec: ConeRec;
[coneMO, moFound] ← DisplayList3d.FindObjectFromName["cone", scene];
IF NOT moFound THEN ERROR;
coneRec ← NARROW[coneMO.mainBody];
We need to know the size of the master object in order to know what scalars to use to achieve a cylinder of the size requested by the user.
radius ← radius/coneRec.radius; height ← height/coneRec.height;
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[coneName, "cone", [radius, height, radius], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE { -- mouseButton = blue
mo, oldMo: MasterObject;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[mo, moFound] ← DisplayList3d.FindObjectFromName["cone", scene];
IF NOT moFound THEN ERROR;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitue a cone for a cluster assembly [%g]",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [radius, height, radius]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddCone
AddTorus: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton,
shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
torusName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
mo, oldMo: MasterObject;
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
bigRadius, sectionRadius: REAL;
moFound: BOOL;
bigRadius ← SVViewerTools.GetReal[editToolData.torusSection.bigRadius, 100];
sectionRadius ← SVViewerTools.GetReal[editToolData.torusSection.sectionRadius, 100];
Create a new torus master object.
mo ← BasicObject3d.TorusMakeMasterObject[torusName, bigRadius, sectionRadius];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
DisplayList3d.AddMasterObjectToScene[mo, scene
! NameAlreadyPresent => {
SVError.Append[Rope.Cat["Torus name ", mo.name, " is already registered. Try another."], TRUE, TRUE];
SVError.Blink[]; addSucceeds ← FALSE; CONTINUE}
];
[newAssembly, moFound, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[torusName, torusName, [1,1,1], scene, superAssembly, Matrix3d.Identity[]];
IF NOT moFound THEN ERROR;
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE { -- mouseButton = blue
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitute a torus for a cluster assembly (%g)",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
mo.name ← DisplayList3d.UniqueObjectNameFrom[mo.name, scene];
DisplayList3d.AddMasterObjectToScene[mo, scene];
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
shape.mo ← mo;
moFound ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT moFound THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
CoordSys.ResetScalars[shape.coordSys, [1, 1, 1]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddTorus
AddRevo: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scratchpad: Viewer ← editToolData.scratchpad;
linesOfLongitude: NAT ← 10;
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
revName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
mo, oldMo: MasterObject;
revMesh: RevoluteMesh;
path: Path;
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
Create a new revolute master object.
path ← Scratchpad2d.GetPath[scratchpad];
IF path.len = 0 THEN {
SVError.Append["There is no 2d shape in the scratchpad", TRUE];
SVError.Blink[];
RETURN};
revMesh ← SweepGeometry.RevoluteSweep[path, linesOfLongitude];
mo ← BasicObject3d.RevoSweepMakeMasterObject[revName, revMesh];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
DisplayList3d.AddMasterObjectToScene[mo, scene
! NameAlreadyPresent => {
SVError.Append[Rope.Cat["Revolute sweep name ", mo.name, " is already registered. Try another."], TRUE, TRUE];
SVError.Blink[]; addSucceeds ← FALSE; CONTINUE}
];
IF NOT addSucceeds THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[revName, revName, [1,1,1], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE { -- mouseButton = blue
OldMoWasRevo: BOOL;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitue a revolute sweep for a cluster assembly [%g]",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
mo.name ← DisplayList3d.UniqueObjectNameFrom[mo.name, scene];
DisplayList3d.AddMasterObjectToScene[mo, scene];
mo.name should be unique, so NameAlreadyPresent would be a surprise.
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
OldMoWasRevo ← Rope.Equal[oldMo.class.name, "revoluteSweep", TRUE];
shape.mo ← mo;
success ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT success THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
If we are replacing an old revolute sweep with a new one, then leave the scalars as they are. Otherwise, set them all to unity.
IF NOT OldMoWasRevo THEN CoordSys.ResetScalars[shape.coordSys, [1, 1, 1]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddRevolute
AddLinear: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scratchpad: Viewer ← editToolData.scratchpad;
scene: Scene ← editToolData.sceneSection.currentScene;
errorRope: Rope.ROPE;
addSucceeds: BOOLTRUE;
sweepOK: BOOLTRUE;
frontDepth, backDepth: REAL;
lengthRope: Rope.ROPE;
mo, oldMo: MasterObject;
linMesh: LinearMesh;
path: Path;
poly: Polygon;
newAssembly, superAssembly, assembly: Assembly;
success: BOOL;
linName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
lengthRope ← ViewerTools.GetContents[editToolData.linSection.depth];
frontDepth ← SVViewerTools.GetReal[editToolData.linSection.depth, 100]/2.0;
backDepth ← -frontDepth;
Create a new linear master object
path ← Scratchpad2d.GetPath[scratchpad];
poly ← SVPolygon2d.PathToPolygon[path];
linMesh ← SweepGeometry.LinearSweep[poly, frontDepth, backDepth
! SweepGeometry.TooFewPointsForShadedSweep => {
SVError.Append["Too few points for a linear sweep.",TRUE,TRUE];
SVError.Blink[];
sweepOK ← FALSE;
CONTINUE;
};
];
IF NOT sweepOK THEN RETURN;
mo ← BasicObject3d.LinSweepMakeMasterObject[linName, linMesh];
IF mouseButton = red OR mouseButton = yellow THEN {
[superAssembly, success] ← SVEditUser.GetParent[editToolData];
IF NOT success THEN RETURN;
DisplayList3d.AddMasterObjectToScene[mo, scene
! NameAlreadyPresent => {
SVError.Append[Rope.Cat["Linear sweep name ", mo.name, " is already registered. Try another."], TRUE, TRUE];
SVError.Blink[]; addSucceeds ← FALSE; CONTINUE}
];
IF NOT addSucceeds THEN RETURN;
[newAssembly, ----, addSucceeds] ←
DisplayList3d.CreateAndAddPrimitiveAssembly[linName, linName, [1,1,1], scene, superAssembly, Matrix3d.Identity[]];
IF NOT addSucceeds THEN RETURN;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssembly, editToolData, scene, newAssembly];
}
ELSE { -- mouseButton = blue. Replace shape.
oldMOWasLinear: BOOL;
shape: Shape;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
IF NOT ISTYPE[assembly.shape, Shape] THEN {
errorRope ← IO.PutFR["Can't substitute a linear sweep for a cluster assembly [%g]",[rope[assembly.name]]];
SVError.Append[errorRope, TRUE, TRUE];
SVError.Blink[];
RETURN};
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
mo.name ← DisplayList3d.UniqueObjectNameFrom[mo.name, scene];
DisplayList3d.AddMasterObjectToScene[mo, scene];
mo.name should be unique, so SIGNAL NameAlreadyPresent would be a surprise.
shape ← NARROW[assembly.shape];
oldMo ← shape.mo;
oldMOWasLinear ← Rope.Equal[oldMo.class.name, "linearSweep", TRUE];
shape.mo ← mo;
success ← DisplayList3d.DeleteMasterObjectIfUnused[oldMo, scene];
IF NOT success THEN {
SVError.Append[Rope.Cat["Old master object ", oldMo.name, "mysteriously disappeared. Save your work"], TRUE, TRUE];
SVError.Blink[] };
Leave assembly.scalars alone if the old master object was also a linear sweep. Otherwise, set them all to unity.
IF NOT oldMOWasLinear THEN CoordSys.ResetScalars[shape.coordSys, [1, 1, 1]];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, assembly];
};
}; -- end of AddLinear
Copy: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
parentToBe, assembly, assemblyCopy: Assembly;
found, success: BOOL;
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
[parentToBe, found] ← SVEditUser.GetParent[editToolData];
IF NOT found THEN RETURN;
success ← TRUE;
assemblyCopy ← DisplayList3d.CopyAssemblyAndSonsUniqueNames[assembly, scene, scene, parentToBe
!DisplayList3d.NameAlreadyPresent => {success ← FALSE; CONTINUE}];
IF NOT success THEN {
SVError.Append["Some name in assembly is already present", TRUE, TRUE];
SVError.Blink[];
RETURN;
};
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
Since the copy is on top of the original, there is no need to redraw.
}; -- end of Copy
Rename: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton, shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
assembly: Assembly;
oldName: Rope.ROPE;
newName: Rope.ROPE ← ViewerTools.GetContents[editToolData.sceneSection.new];
assembly ← SVSelections.TopMoveeCoincident[];
IF assembly = NIL THEN RETURN;
oldName ← assembly.name;
DisplayList3d.RenameAssembly[assembly, newName, scene];
SVError.Append[Rope.Cat["Assembly ", oldName, " renamed to ", newName, "."], TRUE, TRUE];
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
};
NewParent: PUBLIC PROC [parent: REF ANY, clientData: REF ANY, mouseButton: MouseButton,
shift, control: BOOL] = TRUSTED {
editToolData: EditToolData ← NARROW[clientData];
scene: Scene ← editToolData.sceneSection.currentScene;
parentToBe: Assembly;
found, parentIsPrimitive: BOOL;
g: SelectionGenerator;
selectionsExist: BOOL;
[g, selectionsExist] ← SVSelections.GetSelectionGenerator[movee];
SVSelections.ComplainIfNot[selectionsExist];
IF NOT selectionsExist THEN RETURN;
[parentToBe, found] ← SVEditUser.GetParent[editToolData];
IF NOT found THEN RETURN;
FOR assembly: Assembly ← SVSelections.NextSelectionCoincident[g], SVSelections.NextSelectionCoincident[g] UNTIL assembly = NIL DO
DisplayList3d.MoveSubassembly[assembly, parentToBe, scene
!DisplayList3d.AttemptToAddSubassemblyToPrimitive =>
{parentIsPrimitive ← TRUE; CONTINUE}];
IF parentIsPrimitive THEN GOTO PrimitiveParent;
REPEAT
PrimitiveParent => {
SVError.Append["A primitive can't be a parent.", TRUE, TRUE];
SVError.Blink[];
};
ENDLOOP;
SVEditUser.SceneNewVersion[editToolData.currentViewerToolData];
};
END.