<> <> <> <> <> <<>> DIRECTORY CoordSys, Imager, ImagerBackdoor, Feedback, Matrix3d, Rope, SV2d, SV3d, SVAssembly, SVDraw3d, SVEditUser, SVInterfaceTypes, SVModelTypes, SVRayTypes, SVScene, SVSceneTypes, SVSelections, SVVector3d, SVWindow; SVSelectionsImpl: CEDAR PROGRAM IMPORTS CoordSys, Feedback, Imager, ImagerBackdoor, Matrix3d, SVAssembly, SVDraw3d, SVEditUser, SVScene, SVVector3d, SVWindow EXPORTS SVSelections = BEGIN Slice: TYPE = SVSceneTypes.Slice; Camera: TYPE = SVModelTypes.Camera; CoordSystem: TYPE = SVModelTypes.CoordSystem; EditToolData: TYPE = SVInterfaceTypes.EditToolData; MasterObject: TYPE = SVSceneTypes.MasterObject; Matrix4by4: TYPE = SV3d.Matrix4by4; Point2d: TYPE = SV2d.Point2d; Point3d: TYPE = SV3d.Point3d; Primitive: TYPE = SVRayTypes.Primitive; Scene: TYPE = SVSceneTypes.Scene; ToolData: TYPE = SVSceneTypes.ToolData; SVData: TYPE = SVInterfaceTypes.SVData; Vector3d: TYPE = SV3d.Vector3d; globalTargetList: LIST OF Selection _ NIL; globalMoveeList: LIST OF Selection _ NIL; globalPlaneList: LIST OF Selection _ NIL; <> Skitter: TYPE = REF SkitterObj; SkitterObj: TYPE = SVInterfaceTypes.SkitterObj; SkitterMode: TYPE = SVSceneTypes.SkitterMode; -- {surface, extend, coordframe} <> UpdateSkitter: PUBLIC PROC [assembly: Slice, primitive: Primitive, svData: SVData] = { editToolData: EditToolData _ svData.editToolData; globalSkitter: Skitter _ editToolData.skitter; globalSkitter.assembly _ assembly; globalSkitter.primitive _ primitive; globalSkitter.svData _ svData; IF assembly # NIL THEN { SVEditUser.SetCurrentAssemblyName[assembly, svData.editToolData]; globalSkitter.alive _ TRUE; } ELSE globalSkitter.alive _ FALSE; }; SetModeSkitter: PUBLIC PROC [svData: SVData, mode: SkitterMode] = { editToolData: EditToolData _ svData.editToolData; globalSkitter: Skitter _ editToolData.skitter; globalSkitter.mode _ mode; }; PositionSkitterFromFrame: PUBLIC PROC [svData: SVData, cameraPoint: Point2d, skitterWORLD: Matrix4by4] = { editToolData: EditToolData _ svData.editToolData; globalSkitter: Skitter _ editToolData.skitter; globalSkitter.alive _ TRUE; globalSkitter.cameraPoint _ cameraPoint; globalSkitter.skitterWORLD _ skitterWORLD; }; MakeAlignedMat: PROC [worldNormal: Vector3d, surfacePtInWorld: Point3d, cs: CoordSystem] RETURNS [mat: Matrix4by4] = { <> yAxisOfCS: Vector3d _ Matrix3d.YAxisOfMatrix[CoordSys.WRTWorld[cs]]; xAxis: Vector3d; IF SVVector3d.Parallel[yAxisOfCS, worldNormal] THEN { xAxis _ Matrix3d.XAxisOfMatrix[CoordSys.WRTWorld[cs]]; IF AntiParallel[yAxisOfCS, worldNormal] THEN xAxis _ SVVector3d.Negate[xAxis]; <> } ELSE xAxis _ SVVector3d.CrossProduct[yAxisOfCS, worldNormal]; mat _ Matrix3d.MakeMatFromZandXAxis[worldNormal, xAxis, surfacePtInWorld]; }; AntiParallel: PROC [v1, v2: Vector3d] RETURNS [BOOL] = { RETURN[Sign[v1[1]] = -Sign[v2[1]] OR Sign[v1[2]] = -Sign[v2[2]] OR Sign[v1[3]] = -Sign[v2[3]] ]; }; Sign: PROC [r: REAL] RETURNS [INT] = { IF r = 0.0 THEN RETURN[2]; IF r < 0.0 THEN RETURN[-1] ELSE RETURN[1]; }; PositionSkitter: PUBLIC PROC [cameraPoint: Point2d, originWorld: Point3d, normalWorld: Vector3d, assembly: Slice, svData: SVData] RETURNS [skitterWORLD: Matrix4by4] = { IF assembly # NIL THEN { skitterWORLD _ MakeAlignedMat[normalWorld, originWorld, assembly.coordSys]; UpdateSkitter[assembly, NIL, svData]; } ELSE { skitterWORLD _ Matrix3d.MakeHorizontalMatFromZAxis[normalWorld, originWorld]; UpdateSkitter[NIL, NIL, svData]; }; PositionSkitterFromFrame[svData, cameraPoint, skitterWORLD]; }; <> <> <> <> <> <> <<};>> <> <> <<};>> <<>> KillSkitter: PUBLIC PROC [editToolData: EditToolData] = { <> globalSkitter: Skitter _ editToolData.skitter; globalSkitter.alive _ FALSE; globalSkitter.assembly _ NIL; globalSkitter.primitive _ NIL; globalSkitter.svData _ NIL; SVEditUser.SetCurrentAssemblyName[NIL, editToolData]; }; IsAliveSkitter: PUBLIC PROC [editToolData: EditToolData] RETURNS [BOOL] = { globalSkitter: Skitter _ editToolData.skitter; RETURN[globalSkitter.alive]; }; GetSkitterData: PUBLIC PROC [editToolData: EditToolData] RETURNS [assembly: Slice, primitive: Primitive, svData: SVData] = { globalSkitter: Skitter _ editToolData.skitter; IF globalSkitter.alive THEN { assembly _ globalSkitter.assembly; primitive _ globalSkitter.primitive; svData _ NARROW[globalSkitter.svData]; } ELSE { assembly _ NIL; primitive _ NIL; svData _ NIL; Feedback.AppendRaw[$Solidviews, "Please make a skitter selection first.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; }; }; GetModeSkitter: PUBLIC PROC [editToolData: EditToolData] RETURNS [mode: SkitterMode] = { globalSkitter: Skitter _ editToolData.skitter; IF globalSkitter.alive THEN mode _ globalSkitter.mode ELSE { mode _ coordframe; Feedback.AppendRaw[$Solidviews, "Get Mode Skitter: There is no skitter.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; }; }; GetPositionSkitter: PUBLIC PROC [editToolData: EditToolData] RETURNS [cameraPoint: Point2d, skitterWORLD: Matrix4by4] = { globalSkitter: Skitter _ editToolData.skitter; IF globalSkitter.alive THEN { cameraPoint _ globalSkitter.cameraPoint; skitterWORLD _ globalSkitter.skitterWORLD; } ELSE { cameraPoint _ [0,0]; skitterWORLD _ Matrix3d.Identity[]; Feedback.AppendRaw[$Solidviews, "Get Position Skitter: There is no skitter.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; }; }; <> AddHookFromSkitter: PUBLIC PROC [editToolData: EditToolData] RETURNS [assembly: Slice] = { <> globalSkitter: Skitter _ editToolData.skitter; svData: SVData _ NARROW[globalSkitter.svData]; scene: Scene _ svData.scene; addSucceeds: BOOL _ TRUE; currentCS: CoordSystem _ globalSkitter.assembly.coordSys; jackName: Rope.ROPE; hooksuper: Matrix4by4; hookCS: CoordSystem; jackName _ CoordSys.UniqueNameWithSuffix[globalSkitter.assembly.name, "Hook", scene.coordSysRoot]; hooksuper _ Matrix3d.AInTermsOfB[globalSkitter.skitterWORLD, CoordSys.WRTWorld[currentCS]]; hookCS _ CoordSys.CreateCoordSysInTree[jackName, hooksuper, currentCS, scene.coordSysRoot]; [assembly, addSucceeds] _ SVAssembly.CreatePrimitiveAtExistingCoordSys[jackName, "jack", [50, 50, 50], scene, hookCS]; IF NOT addSucceeds THEN RETURN; assembly.sittingOn _ globalSkitter.assembly.name; SVAssembly.ConnectAssemblyToParent[assembly, scene.assembly]; <> }; AddFloaterFromSkitter: PUBLIC PROC [editToolData: EditToolData] RETURNS [assembly: Slice] = { <> globalSkitter: Skitter _ editToolData.skitter; svData: SVData _ NARROW[globalSkitter.svData]; scene: Scene _ svData.scene; addSucceeds: BOOL _ TRUE; jackName: Rope.ROPE; sceneAssemblyCS: CoordSystem _ scene.assembly.coordSys; floatersuper: Matrix4by4; floaterCS: CoordSystem; jackName _ CoordSys.UniqueNameFrom["Floater", scene.coordSysRoot]; floatersuper _ Matrix3d.AInTermsOfB[globalSkitter.skitterWORLD, CoordSys.WRTWorld[sceneAssemblyCS]]; floaterCS _ CoordSys.CreateCoordSysInTree[jackName, floatersuper, sceneAssemblyCS, scene.coordSysRoot]; [assembly, ----] _ SVAssembly.CreatePrimitiveAtExistingCoordSys[jackName, "jack", [50, 50, 50], scene, floaterCS]; IF NOT addSucceeds THEN RETURN; SVAssembly.ConnectAssemblyToParent[assembly, scene.assembly]; <> }; <> <<1) A Floater's coordSys>> <<2) A Hook coordSys>> <<3) An Object's coordSys.>> <> <<1) A hook movee selects an object to be tugged and a tugboat at the same time.>> <<2) A floater, hook, or object selection allows the selected coordSys to be moved. A hook might be moved around on a surface or might become a floater. An object moves along with its children. A floater moves in space.>> <<3) The origin of an in-scene ray is specified.>> <<4) The origin of a floater calculation is specified.>> <> <<1) Any target can be a center of rotation, a base frame for translation.>> <<2) All selectable objects are also assemblies in the scene tree. All assemblies have an associated distinguished plane. Hence a target can suggest a plane to be used for dragging.>> <<3) The direction point of an in-scene ray is specified.>> <<4) The end point of a floater calculation is specified.>> <<>> <> Selection: TYPE = REF SelectionObj; SelectionObj: TYPE = SVInterfaceTypes.SelectionObj; ReferentType: TYPE = SVInterfaceTypes.ReferentType; -- {hook, floater, coordSys}; SelectionType: TYPE = SVInterfaceTypes.SelectionType; -- {target, movee, plane}; <> <<1) The global skitter.>> <<2) A stack of all movee selections.>> <<3) A stack of all target selections.>> <<>> CreateHookMovee: PUBLIC PROC [jack: Slice, indirect: Slice, svData: SVData] RETURNS [movee: Selection] = { movee _ NEW[SelectionObj _ [jack, indirect, svData, hook, movee]]; }; CreateCoordSysMovee: PUBLIC PROC [coincident: Slice, svData: SVData] RETURNS [movee: Selection] = { movee _ NEW[SelectionObj _ [coincident, NIL, svData, coordSys, movee]]; }; CreateHookTarget: PUBLIC PROC [jack: Slice, indirect: Slice, svData: SVData] RETURNS [target: Selection] = { target _ NEW[SelectionObj _ [jack, indirect, svData, hook, target]]; }; CreateCoordSysTarget: PUBLIC PROC [coincident: Slice, svData: SVData] RETURNS [target: Selection] = { target _ NEW[SelectionObj _ [coincident, NIL, svData, coordSys, target]]; }; CreatePlaneSelection: PUBLIC PROC [coincident: Slice, svData: SVData] RETURNS [planeSel: Selection] = { planeSel _ NEW[SelectionObj _ [coincident, NIL, svData, coordSys, plane]]; SVScene.AddOrResizeToolToAssembly[coincident, svData.scene]; }; SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator; SelectionGeneratorObj: TYPE = SVInterfaceTypes.SelectionGeneratorObj; GetSelectionGenerator: PUBLIC PROC [selectType: SelectionType] RETURNS [g: SelectionGenerator, selectionsExist: BOOL] = { SELECT selectType FROM movee => { g _ NEW[SelectionGeneratorObj _ [currentPtr: globalMoveeList]]; selectionsExist _ (NOT globalMoveeList = NIL); }; target => { g _ NEW[SelectionGeneratorObj _ [currentPtr: globalTargetList]]; selectionsExist _ (NOT globalTargetList = NIL); }; plane => { g _ NEW[SelectionGeneratorObj _ [currentPtr: globalPlaneList]]; selectionsExist _ (NOT globalPlaneList = NIL); }; ENDCASE => ERROR; }; ComplainIfNot: PUBLIC PROC [selectionsExist: BOOL] = { IF NOT selectionsExist THEN { Feedback.AppendRaw[$Solidviews, "There are no source selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; }; }; NextSelection: PUBLIC PROC [g: SelectionGenerator] RETURNS [sel: Selection] = { IF g.currentPtr = NIL THEN RETURN[NIL]; sel _ g.currentPtr.first; g.currentPtr _ g.currentPtr.rest; }; NextSelectionCoincident: PUBLIC PROC [g: SelectionGenerator] RETURNS [coin: Slice] = { IF g.currentPtr = NIL THEN RETURN[NIL]; coin _ g.currentPtr.first.coincident; g.currentPtr _ g.currentPtr.rest; }; PushMovee: PUBLIC PROC [moveeSel: Selection] = { globalMoveeList _ CONS[moveeSel, globalMoveeList]; SVEditUser.SetSourceName[moveeSel.coincident, moveeSel.svData.editToolData]; }; PopMovee: PUBLIC PROC [] RETURNS [moveeSel: Selection] = { newTop: Selection; IF globalMoveeList = NIL THEN { moveeSel _ NIL; Feedback.AppendRaw[$Solidviews, "There are no source selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE { moveeSel _ globalMoveeList.first; globalMoveeList _ globalMoveeList.rest; newTop _ IF globalMoveeList = NIL THEN NIL ELSE globalMoveeList.first; IF newTop # NIL THEN SVEditUser.SetSourceName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetSourceName[NIL, moveeSel.svData.editToolData]; }; }; NextMovee: PUBLIC PROC [] RETURNS [moveeSel: Selection] = { <> newTop: Selection; IF globalMoveeList = NIL THEN moveeSel _ NIL ELSE { moveeSel _ globalMoveeList.first; globalMoveeList _ globalMoveeList.rest; newTop _ IF globalMoveeList = NIL THEN NIL ELSE globalMoveeList.first; IF newTop # NIL THEN SVEditUser.SetSourceName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetSourceName[NIL, moveeSel.svData.editToolData]; }; }; PopMoveeCoincident: PUBLIC PROC [] RETURNS [movee: Slice] = { newTop: Selection; moveeSel: Selection; IF globalMoveeList = NIL THEN { movee _ NIL; Feedback.AppendRaw[$Solidviews, "There are no source selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE { moveeSel _ globalMoveeList.first; movee _ moveeSel.coincident; globalMoveeList _ globalMoveeList.rest; newTop _ IF globalMoveeList = NIL THEN NIL ELSE globalMoveeList.first; IF newTop # NIL THEN SVEditUser.SetSourceName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetSourceName[NIL, moveeSel.svData.editToolData]; }; }; NextMoveeCoincident: PUBLIC PROC [] RETURNS [movee: Slice] = { <> newTop: Selection; moveeSel: Selection; IF globalMoveeList = NIL THEN movee _ NIL ELSE { moveeSel _ globalMoveeList.first; movee _ moveeSel.coincident; globalMoveeList _ globalMoveeList.rest; newTop _ IF globalMoveeList = NIL THEN NIL ELSE globalMoveeList.first; IF newTop # NIL THEN SVEditUser.SetSourceName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetSourceName[NIL, moveeSel.svData.editToolData]; }; }; TopMovee: PUBLIC PROC [] RETURNS [moveeSel: Selection] = { IF globalMoveeList = NIL THEN moveeSel _ NIL ELSE moveeSel _ globalMoveeList.first; }; TopMoveeC: PUBLIC PROC [] RETURNS [moveeSel: Selection] = { <> IF globalTargetList = NIL THEN { moveeSel _ NIL; Feedback.AppendRaw[$Solidviews, "There are no source selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE moveeSel _ globalTargetList.first; }; TopMoveeCoincident: PUBLIC PROC [] RETURNS [movee: Slice] = { IF globalMoveeList = NIL THEN movee _ NIL ELSE movee _ globalMoveeList.first.coincident; }; ClearMoveeStack: PUBLIC PROC [editToolData: EditToolData] = { <> ComplementAllSelections[movee]; globalMoveeList _ NIL; SVEditUser.SetSourceName[NIL, editToolData]; }; PushTarget: PUBLIC PROC [targetSel: Selection] = { globalTargetList _ CONS[targetSel, globalTargetList]; SVEditUser.SetTargetName[targetSel.coincident, targetSel.svData.editToolData]; }; PopTarget: PUBLIC PROC [] RETURNS [targetSel: Selection] = { newTop: Selection; IF globalTargetList = NIL THEN { targetSel _ NIL; Feedback.AppendRaw[$Solidviews, "There are no target selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE { targetSel _ globalTargetList.first; globalTargetList _ globalTargetList.rest; newTop _ IF globalTargetList = NIL THEN NIL ELSE globalTargetList.first; IF newTop # NIL THEN SVEditUser.SetTargetName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetTargetName[NIL, targetSel.svData.editToolData]; }; }; NextTarget: PUBLIC PROC [] RETURNS [targetSel: Selection] = { <> newTop: Selection; IF globalTargetList = NIL THEN targetSel _ NIL ELSE { targetSel _ globalTargetList.first; globalTargetList _ globalTargetList.rest; newTop _ IF globalTargetList = NIL THEN NIL ELSE globalTargetList.first; IF newTop # NIL THEN SVEditUser.SetTargetName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetTargetName[NIL, targetSel.svData.editToolData]; }; }; PopTargetCoincident: PUBLIC PROC [] RETURNS [target: Slice] = { targetSel, newTop: Selection; IF globalTargetList = NIL THEN { target _ NIL; Feedback.AppendRaw[$Solidviews, "There are no target selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE { targetSel _ globalTargetList.first; target _ targetSel.coincident; globalTargetList _ globalTargetList.rest; newTop _ IF globalTargetList = NIL THEN NIL ELSE globalTargetList.first; IF newTop # NIL THEN SVEditUser.SetTargetName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetTargetName[NIL, targetSel.svData.editToolData]; }; }; NextTargetCoincident: PUBLIC PROC [] RETURNS [target: Slice] = { <> targetSel, newTop: Selection; IF globalTargetList = NIL THEN target _ NIL ELSE { targetSel _ globalTargetList.first; target _ targetSel.coincident; globalTargetList _ globalTargetList.rest; newTop _ IF globalTargetList = NIL THEN NIL ELSE globalTargetList.first; IF newTop # NIL THEN SVEditUser.SetTargetName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetTargetName[NIL, targetSel.svData.editToolData]; }; }; TopTarget: PUBLIC PROC [] RETURNS [targetSel: Selection] = { IF globalTargetList = NIL THEN targetSel _ NIL ELSE targetSel _ globalTargetList.first; }; TopTargetC: PUBLIC PROC [] RETURNS [targetSel: Selection] = { IF globalTargetList = NIL THEN { targetSel _ NIL; Feedback.AppendRaw[$Solidviews, "There are no target selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE targetSel _ globalTargetList.first; }; TopTargetCoincident: PUBLIC PROC [] RETURNS [target: Slice] = { IF globalTargetList = NIL THEN { target _ NIL; Feedback.AppendRaw[$Solidviews, "There are no target selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE target _ globalTargetList.first.coincident; }; TopTargetCoinCoordSys: PUBLIC PROC [] RETURNS [targetCS: CoordSystem] = { IF globalTargetList = NIL THEN targetCS _ NIL ELSE targetCS _ globalTargetList.first.coincident.coordSys; }; TopTargetCoinCoordSysC: PUBLIC PROC [] RETURNS [targetCS: CoordSystem] = { IF globalTargetList = NIL THEN { targetCS _ NIL; Feedback.AppendRaw[$Solidviews, "There are no target selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE targetCS _ globalTargetList.first.coincident.coordSys; }; ClearTargetStack: PUBLIC PROC [editToolData: EditToolData] = { <> ComplementAllSelections[target]; globalTargetList _ NIL; SVEditUser.SetTargetName[NIL, editToolData]; }; PushPlane: PUBLIC PROC [planeSel: Selection] = { globalPlaneList _ CONS[planeSel, globalPlaneList]; SVEditUser.SetPlaneName[planeSel.coincident, planeSel.svData.editToolData]; }; PopPlane: PUBLIC PROC [] RETURNS [planeSel: Selection] = { newTop: Selection; IF globalPlaneList = NIL THEN { planeSel _ NIL; Feedback.AppendRaw[$Solidviews, "There are no plane selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE { planeSel _ globalPlaneList.first; globalPlaneList _ globalPlaneList.rest; newTop _ IF globalPlaneList = NIL THEN NIL ELSE globalPlaneList.first; IF newTop # NIL THEN SVEditUser.SetPlaneName[newTop.coincident, newTop.svData.editToolData] ELSE SVEditUser.SetPlaneName[NIL, planeSel.svData.editToolData]; }; }; TopPlane: PUBLIC PROC [] RETURNS [planeSel: Selection] = { IF globalPlaneList = NIL THEN planeSel _ NIL ELSE planeSel _ globalPlaneList.first; }; TopPlaneC: PUBLIC PROC [] RETURNS [planeSel: Selection] = { IF globalPlaneList = NIL THEN { planeSel _ NIL; Feedback.AppendRaw[$Solidviews, "There are no plane selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE planeSel _ globalPlaneList.first; }; TopPlaneCoincident: PUBLIC PROC [] RETURNS [planeAssem: Slice] = { IF globalPlaneList = NIL THEN { planeAssem _ NIL; Feedback.AppendRaw[$Solidviews, "There are no plane selections.", oneLiner]; Feedback.BlinkRaw[$Solidviews]; } ELSE planeAssem _ globalPlaneList.first.coincident; }; PlaneStackEmpty: PUBLIC PROC [] RETURNS [BOOL] = { RETURN[globalPlaneList = NIL]; }; ClearPlaneStack: PUBLIC PROC [editToolData: EditToolData] = { ComplementAllSelections[plane]; globalPlaneList _ NIL; SVEditUser.SetPlaneName[NIL, editToolData]; }; ComplementAnySelectionsOnDC: PUBLIC PROC [dc: Imager.Context, assembly: Slice, scene: Scene] = { g: SelectionGenerator; selectionsExist: BOOL; camera: Camera; svData: SVData; FOR type: SelectionType IN [target..plane] DO [g, selectionsExist] _ GetSelectionGenerator[type]; IF NOT selectionsExist THEN LOOP; FOR sel: Selection _ NextSelection[g], NextSelection[g] UNTIL sel = NIL DO IF (sel.referentType = hook AND sel.indirect = assembly) OR sel.coincident = assembly THEN { svData _ sel.svData; camera _ svData.camera; SELECT sel.selectionType FROM target => { csCAMERA: Matrix4by4; csCAMERA _ CoordSys.WRTCamera[sel.coincident.coordSys, camera.coordSys]; SVDraw3d.DrawTargetCoordSys[dc, csCAMERA, camera]; }; movee => SVDraw3d.DrawMovee[dc, sel.coincident.coordSys, camera]; plane => { toolData: ToolData; planeAssem: Slice; planeAssem _ sel.coincident; IF planeAssem.toolMasterObject = NIL OR planeAssem.toolMasterObject.mainBody = NIL THEN ERROR; toolData _ NARROW[planeAssem.toolMasterObject.mainBody]; SVDraw3d.DrawPlaneSelection[dc, sel.coincident.coordSys, toolData.plane, camera]; }; ENDCASE => ERROR; }; ENDLOOP; ENDLOOP; }; ComplementSelectionDC: PUBLIC PROC [dc: Imager.Context, sel: Selection, svData: SVData] = { ComplementSelectionDCAux: SAFE PROC = { Imager.SetColor[dc, ImagerBackdoor.invert]; SELECT sel.selectionType FROM target => { csCAMERA: Matrix4by4; csCAMERA _ CoordSys.WRTCamera[sel.coincident.coordSys, camera.coordSys]; SVDraw3d.DrawTargetCoordSys[dc, csCAMERA, camera]; }; movee => SVDraw3d.DrawMovee[dc, sel.coincident.coordSys, camera]; plane => { toolData: ToolData; planeAssem: Slice; planeAssem _ sel.coincident; IF planeAssem.toolMasterObject = NIL OR planeAssem.toolMasterObject.mainBody = NIL THEN ERROR; toolData _ NARROW[planeAssem.toolMasterObject.mainBody]; SVDraw3d.DrawPlaneSelection[dc, sel.coincident.coordSys, toolData.plane, camera]; }; ENDCASE => ERROR; }; camera: Camera; IF svData # sel.svData THEN RETURN; camera _ svData.camera; Imager.DoSave[dc, ComplementSelectionDCAux]; }; ComplementAnySelectionsDCAux: PRIVATE PROC [dc: Imager.Context, selType: SelectionType, svData: SVData, scene: Scene, camera: Camera] = { <> g: SelectionGenerator; selectionsExist: BOOL; [g, selectionsExist] _ GetSelectionGenerator[selType]; IF NOT selectionsExist THEN RETURN; FOR sel: Selection _ NextSelection[g], NextSelection[g] UNTIL sel = NIL DO IF sel.svData = svData THEN { ComplementSelectionDC[dc, sel, svData]; }; ENDLOOP; }; ComplementAllSelections: PUBLIC PROC [selType: SelectionType] = { <> DoComplementSelection: PROC [dc: Imager.Context] = { ComplementSelectionDC[dc, sel, sel.svData]; }; g: SelectionGenerator; selectionsExist: BOOL; scene: Scene; camera: Camera; sel: Selection; [g, selectionsExist] _ GetSelectionGenerator[selType]; IF NOT selectionsExist THEN RETURN; FOR sel _ NextSelection[g], NextSelection[g] UNTIL sel = NIL DO scene _ sel.svData.scene; camera _ sel.svData.camera; <> ENDLOOP; }; KillSkitterAndSelections: PUBLIC PROC [editToolData: EditToolData] = { svData: SVData; camera: Camera; ClearTargetStack[editToolData]; ClearMoveeStack[editToolData]; ClearPlaneStack[editToolData]; IF IsAliveSkitter[editToolData] THEN { [----,----,svData] _ GetSkitterData[editToolData]; IF svData = NIL THEN ERROR; camera _ svData.camera; SVWindow.RestoreScreenAndInvariants[$SkitterMoved, svData]; }; KillSkitter[editToolData]; }; CreateSkitter: PUBLIC PROC [] RETURNS [skitter: Skitter] = { skitter _ NEW[SkitterObj _ [FALSE, [0,0], NIL, NIL, Matrix3d.Identity[], NIL, surface]]; }; END.