<> <> <> <> DIRECTORY BasicObject3d, CoordSys, SVScene, Imager, Matrix3d, Random, Rope, SV2d, SV3d, SVEditUser, SVError, SVInputMonitor, SVInterfaceTypes, SVModelTypes, SVRayTypes, SVSceneTypes, SVSelections, SVTransforms, SVViewer, SVViewerInput, SVViewerTools, SVViewerUser, TIPUser, ViewerClasses; SVViewerInputImplA: PROGRAM IMPORTS CoordSys, SVScene, Matrix3d, Random, Rope, SVEditUser, SVError, SVInputMonitor, SVSelections, SVTransforms, SVViewer, SVViewerInput, SVViewerTools, SVViewerUser EXPORTS SVViewerInput = BEGIN Artwork: TYPE = SVModelTypes.Artwork; ArtworkToolData: TYPE = SVInterfaceTypes.ArtworkToolData; Assembly: TYPE = SVSceneTypes.Assembly; AssemblyList: TYPE = SVSceneTypes.AssemblyList; BoundBox: TYPE = SVModelTypes.BoundBox; BoundSphere: TYPE = SVModelTypes.BoundSphere; Camera: TYPE = SVModelTypes.Camera; Classification: TYPE = SVRayTypes.Classification; Color: TYPE = Imager.Color; CoordSystem: TYPE = SVModelTypes.CoordSystem; CSGTree: TYPE = SVRayTypes.CSGTree; CylinderRec: TYPE = BasicObject3d.CylinderRec; EditToolData: TYPE = SVInterfaceTypes.EditToolData; 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 = SVRayTypes.Primitive; Ray: TYPE = SVRayTypes.Ray; Scene: TYPE = SVSceneTypes.Scene; SearchDepth: TYPE = SVInterfaceTypes.SearchDepth; Selection: TYPE = SVInterfaceTypes.Selection; SelectionGenerator: TYPE = SVInterfaceTypes.SelectionGenerator; Shape: TYPE = SVSceneTypes.Shape; SkitterMode: TYPE = SVInterfaceTypes.SkitterMode; ToolData: TYPE = SVSceneTypes.ToolData; TrigLine: TYPE = SV2d.TrigLine; Vector: TYPE = SV3d.Vector; ViewerToolData: TYPE = SVInterfaceTypes.ViewerToolData; InputNotify: PUBLIC SAFE PROCEDURE [self: ViewerClasses.Viewer, input: LIST OF REF ANY] = TRUSTED { <> viewerToolData: ViewerToolData _ NARROW[self.data]; IF ISTYPE[input.first, TIPUser.TIPScreenCoords] THEN { controlPoint: Point2d; camera: Camera _ viewerToolData.camera; mousePlace: TIPUser.TIPScreenCoords _ NARROW[input.first]; controlPoint[1] _ mousePlace.mouseX; -- this is a fix to float conversion controlPoint[2] _ mousePlace.mouseY; controlPoint _ CoordSys.ScreenToCamera[controlPoint, camera.screenCS]; <> IF ISTYPE[input.rest.first, ATOM] THEN SELECT input.rest.first FROM $StartDrag, $SetDrag, $EndDrag => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartCameraDrag, $SetCameraDrag, $EndCameraDrag => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $SingleRay => SVViewerUser.SingleRay[viewerToolData, controlPoint]; $FrameUpLeft, $FrameDownRightMove, $FrameDownRightEnd, $DeleteFrame => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartSkitter, $DuringSkitter, $EndSkitter => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartBackSkitter, $DuringBackSkitter, $EndBackSkitter => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartTopLevelSkitter, $DuringTopLevelSkitter, $EndTopLevelSkitter => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartCoordSkitter, $DuringCoordSkitter, $EndCoordSkitter => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartTightRope, $DuringTightRope, $EndTightRope => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $StartWallWalk, $DuringWallWalk, $EndWallWalk => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $Paint => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $ExtendSkitter => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; $ExtendCoordSkitter => SVInputMonitor.NewMotion[controlPoint, NARROW[input.rest.first], viewerToolData]; ENDCASE => { SVError.Append["Solid viewer: Unknown mouse action.", TRUE, TRUE]; SVError.Blink[]; } } -- is a Mousepoint ELSE { -- not a mouse-point dependent operation SELECT input.first FROM $ExtendCurrent => ExtendCurrent[viewerToolData]; $ReloadTipTable => SVViewer.ReloadTipTable[viewerToolData]; $RestartProcess => SVInputMonitor.Restart[]; $ClearAllSelections => SVSelections.KillSkitterAndSelections[viewerToolData.editToolData]; $DeleteSources => DeleteSources[viewerToolData]; $NoOp => {}; $AddCylinder => SVViewerInput.AddCylinder[]; $Skewer => SVViewerInput.Skewer[]; $MoveUntilTouch => SVViewerInput.MoveUntilTouch[]; $ArrowShoot => SVViewerInput.ArrowShoot[]; $DropPerpendicular => DropPerpendicular[]; $VolleyShoot => {}; $JackPivotX => SVViewerInput.JackPivotX[viewerToolData, 90]; $JackPivotY => SVViewerInput.JackPivotY[viewerToolData, 90]; $JackPivotZ => SVViewerInput.JackPivotZ[viewerToolData, 90]; $JackPivotXInverse => SVViewerInput.JackPivotX[viewerToolData, -90]; $JackPivotYInverse => SVViewerInput.JackPivotY[viewerToolData, -90]; $JackPivotZInverse => SVViewerInput.JackPivotZ[viewerToolData, -90]; $SourcePivotX => SVViewerInput.SourcePivotX[viewerToolData, 90]; $SourcePivotY => SVViewerInput.SourcePivotY[viewerToolData, 90]; $SourcePivotZ => SVViewerInput.SourcePivotZ[viewerToolData, 90]; $SourcePivotXInverse => SVViewerInput.SourcePivotX[viewerToolData, -90]; $SourcePivotYInverse => SVViewerInput.SourcePivotY[viewerToolData, -90]; $SourcePivotZInverse => SVViewerInput.SourcePivotZ[viewerToolData, -90]; $SourceRotX => SourceRotX[10]; $SourceRotY => SourceRotY[10]; $SourceRotZ => SourceRotZ[10]; $SourceRotXInverse => SourceRotX[-10]; $SourceRotYInverse => SourceRotY[-10]; $SourceRotZInverse => SourceRotZ[-10]; $CopyRandomToAllTargets => CopyRandomToAllTargets[viewerToolData]; $CopyToAllTargets => CopyToAllTargets[viewerToolData]; $CopyToAllTargetsTree => CopyToAllTargetsTree[viewerToolData]; $MoveToTarget => MoveToTarget[viewerToolData]; $CopyRotate => CopyRotate[]; $CycleTool => CycleTool[]; $SetTool => SetTool[]; $ResetTool => ResetTool[]; $ResetSpheres => ResetSpheres[viewerToolData]; $SetBoundingSpheres => SetBoundingSpheres[viewerToolData]; $SetSphereShadows => SetSphereShadows[viewerToolData]; $SkitterMakes => SkitterMakes[]; $SkitterMakesSource => SkitterMakesSource[viewerToolData]; $SkitterMakesTarget => SkitterMakesTarget[viewerToolData]; $SkitterMakesPlane => SkitterMakesPlane[viewerToolData]; $SkitterMakesSourceIndirect => SkitterMakesSourceIndirect[viewerToolData]; $SkitterMakesTargetIndirect => SkitterMakesTargetIndirect[viewerToolData]; $SkitterMakesSourceIndirectOnly => SkitterMakesSourceIndirectOnly[viewerToolData]; $SkitterMakesTargetIndirectOnly => SkitterMakesTargetIndirectOnly[viewerToolData]; $SkitterMakesPlaneIndirectOnly => SkitterMakesPlaneIndirectOnly[viewerToolData]; ENDCASE => { SVError.Append["Solid viewer: Unknown command.", TRUE, TRUE]; SVError.Blink[]; } }; }; -- end of InputNotify DeleteSources: PROC [viewerToolData: ViewerToolData] = { scene: Scene _ viewerToolData.scene; SVEditUser.DeleteSources[viewerToolData.editToolData]; }; SetBoundingSpheres: PROC [viewerToolData: ViewerToolData] = { camera: Camera _ viewerToolData.camera; camera.useBoundBoxes _ FALSE; }; SetSphereShadows: PROC [viewerToolData: ViewerToolData] = { camera: Camera _ viewerToolData.camera; camera.useBoundSpheresForShadows _ TRUE; }; ResetSpheres: PROC [viewerToolData: ViewerToolData] = { camera: Camera _ viewerToolData.camera; camera.useBoundBoxes _ TRUE; camera.useBoundSpheresForShadows _ FALSE; }; ComplementSkitter: PUBLIC PROC [] = { viewerToolData: ViewerToolData; camera: Camera; DoComplementSkitter: PROC [dc: Imager.Context] = { SVSelections.ComplementSkitter[dc, camera]; }; IF NOT SVSelections.IsAliveSkitter[] THEN RETURN; [----,----,viewerToolData] _ SVSelections.GetSkitterData[]; IF viewerToolData = NIL THEN ERROR; camera _ viewerToolData.camera; SVViewerUser.Painter[DoComplementSkitter, viewerToolData]; }; SkitterMakes: PUBLIC PROC [] = { viewerToolData: ViewerToolData; [----,----,viewerToolData] _ SVSelections.GetSkitterData[]; [] _ SkitterMakesAux[viewerToolData]; ComplementSkitter[]; -- erase the skitter SVSelections.KillSkitter[viewerToolData.editToolData]; }; SkitterMakesAux: PROC [viewerToolData: ViewerToolData] RETURNS [coincident: Assembly] = { <> scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; SELECT skitterMode FROM surface => { coincident _ SVSelections.AddHookFromSkitter[]; SVViewerUser.ComplementAssembly[viewerToolData, coincident]; -- Draw the hook }; tightrope => { coincident _ SVSelections.AddFloaterFromSkitter[]; SVViewerUser.ComplementAssembly[viewerToolData, coincident]; -- Draw the floater }; coordframe => { [coincident,----,----] _ SVSelections.GetSkitterData[]; }; ENDCASE => ERROR; }; SkitterMakesSource: PROC [viewerToolData: ViewerToolData] = { <> skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; coincident: Assembly; movee: Selection; DrawLatestMovee: PROC [dc: Imager.Context] = { SVSelections.ComplementReferentDC[dc, movee, viewerToolData]; -- erase the Jack if any SVSelections.ComplementSelectionDC[dc, movee, viewerToolData]; -- draw selection instead. }; coincident _ SkitterMakesAux[viewerToolData]; IF coincident = NIL THEN RETURN; <> SELECT skitterMode FROM surface => { skitterAssem: Assembly; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; movee _ SVSelections.CreateHookMovee[coincident, skitterAssem, viewerToolData]; SVSelections.PushMovee[movee]; }; tightrope => { movee _ SVSelections.CreateCoordSysMovee[coincident, viewerToolData]; SVSelections.PushMovee[movee]; }; coordframe => { movee _ SVSelections.CreateCoordSysMovee[coincident, viewerToolData]; SVSelections.PushMovee[movee]; }; ENDCASE => ERROR; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestMovee, viewerToolData]; }; SkitterMakesTarget: PROC [viewerToolData: ViewerToolData] = { <> skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; coincident: Assembly; target: Selection; DrawLatestTarget: PROC [dc: Imager.Context] = { SVSelections.ComplementReferentDC[dc, target, viewerToolData]; SVSelections.ComplementSelectionDC[dc, target, viewerToolData]; }; coincident _ SkitterMakesAux[viewerToolData]; -- create and draw the jack IF coincident = NIL THEN RETURN; SELECT skitterMode FROM surface => { skitterAssem: Assembly; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; target _ SVSelections.CreateHookTarget[coincident, skitterAssem, viewerToolData]; SVSelections.PushTarget[target]; }; tightrope => { target _ SVSelections.CreateCoordSysTarget[coincident, viewerToolData]; SVSelections.PushTarget[target]; }; coordframe => { target _ SVSelections.CreateCoordSysTarget[coincident, viewerToolData]; SVSelections.PushTarget[target]; }; ENDCASE => ERROR; ComplementSkitter[]; -- erase the skitter SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestTarget, viewerToolData]; }; SkitterMakesPlane: PROC [viewerToolData: ViewerToolData] = { <> scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; coincident: Assembly; planeSel: Selection; DrawLatestPlane: PROC [dc: Imager.Context] = { SVSelections.ComplementReferentDC[dc, planeSel, viewerToolData]; -- erase the Jack if any SVSelections.ComplementSelectionDC[dc, planeSel, viewerToolData]; -- draw selection instead. }; coincident _ SkitterMakesAux[viewerToolData]; IF coincident = NIL THEN RETURN; <> planeSel _ SVSelections.CreatePlaneSelection[coincident, viewerToolData]; SVSelections.PushPlane[planeSel]; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestPlane, viewerToolData]; }; SkitterMakesSourceIndirect: PROC [viewerToolData: ViewerToolData] = { <> skitterAssem: Assembly; skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; indirect: Assembly; sourceSel: Selection; camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; found: BOOL; DrawLatestMovee: PROC [dc: Imager.Context] = { SVSelections.ComplementSelectionDC[dc, sourceSel, viewerToolData]; -- draw selection. }; IF skitterMode # coordframe THEN { SVError.Append["Can only select indirect with a coordframe skitter.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; IF skitterAssem.sittingOn = NIL THEN { SVError.Append[Rope.Concat[skitterAssem.name, " is not sitting on anything."], TRUE, TRUE]; SVError.Blink[]; RETURN; }; [indirect, ----, found] _ SVEditUser.FindAssemblyFromName[skitterAssem.sittingOn, scene]; IF NOT found THEN RETURN; sourceSel _ SVSelections.CreateHookMovee[skitterAssem, indirect, viewerToolData]; SVSelections.PushMovee[sourceSel]; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestMovee, viewerToolData]; }; << >> SkitterMakesTargetIndirect: PROC [viewerToolData: ViewerToolData] = { <> skitterAssem: Assembly; skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; indirect: Assembly; targetSel: Selection; camera: Camera _ viewerToolData.camera; scene: Scene _ viewerToolData.scene; found: BOOL; DrawLatestTarget: PROC [dc: Imager.Context] = { SVSelections.ComplementSelectionDC[dc, targetSel, viewerToolData]; -- draw selection. }; IF skitterMode # coordframe THEN { SVError.Append["Can only select indirect with a coordframe skitter.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; IF skitterAssem.sittingOn = NIL THEN { SVError.Append[Rope.Concat[skitterAssem.name, " is not sitting on anything."], TRUE, TRUE]; SVError.Blink[]; RETURN; }; [indirect, ----, found] _ SVEditUser.FindAssemblyFromName[skitterAssem.sittingOn, scene]; IF NOT found THEN RETURN; targetSel _ SVSelections.CreateHookTarget[skitterAssem, indirect, viewerToolData]; SVSelections.PushTarget[targetSel]; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestTarget, viewerToolData]; }; << >> SkitterMakesSourceIndirectOnly: PROC [viewerToolData: ViewerToolData] = { <> skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; coincident: Assembly; movee: Selection; DrawLatestMovee: PROC [dc: Imager.Context] = { SVSelections.ComplementReferentDC[dc, movee, viewerToolData]; -- erase the Jack if any SVSelections.ComplementSelectionDC[dc, movee, viewerToolData]; -- draw selection instead. }; SELECT skitterMode FROM surface => { skitterAssem: Assembly; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; movee _ SVSelections.CreateCoordSysMovee[skitterAssem, viewerToolData]; SVSelections.PushMovee[movee]; }; tightrope => { coincident _ SVSelections.AddFloaterFromSkitter[]; SVViewerUser.ComplementAssembly[viewerToolData, coincident]; -- Draw the floater movee _ SVSelections.CreateCoordSysMovee[coincident, viewerToolData]; SVSelections.PushMovee[movee]; }; coordframe => { [coincident,----,----] _ SVSelections.GetSkitterData[]; movee _ SVSelections.CreateCoordSysMovee[coincident, viewerToolData]; SVSelections.PushMovee[movee]; }; ENDCASE => ERROR; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestMovee, viewerToolData]; }; << >> SkitterMakesTargetIndirectOnly: PROC [viewerToolData: ViewerToolData] = { <> skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; coincident: Assembly; targetSel: Selection; DrawLatestMovee: PROC [dc: Imager.Context] = { SVSelections.ComplementReferentDC[dc, targetSel, viewerToolData]; -- erase the Jack if any SVSelections.ComplementSelectionDC[dc, targetSel, viewerToolData]; -- draw selection instead. }; SELECT skitterMode FROM surface => { skitterAssem: Assembly; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; targetSel _ SVSelections.CreateCoordSysTarget[skitterAssem, viewerToolData]; SVSelections.PushTarget[targetSel]; }; tightrope => { coincident _ SVSelections.AddFloaterFromSkitter[]; SVViewerUser.ComplementAssembly[viewerToolData, coincident]; -- Draw the floater targetSel _ SVSelections.CreateCoordSysTarget[coincident, viewerToolData]; SVSelections.PushTarget[targetSel]; }; coordframe => { [coincident,----,----] _ SVSelections.GetSkitterData[]; targetSel _ SVSelections.CreateCoordSysTarget[coincident, viewerToolData]; SVSelections.PushTarget[targetSel]; }; ENDCASE => ERROR; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestMovee, viewerToolData]; }; << >> SkitterMakesPlaneIndirectOnly: PROC [viewerToolData: ViewerToolData] = { <> skitterMode: SkitterMode _ SVSelections.GetModeSkitter[]; scene: Scene _ viewerToolData.scene; camera: Camera _ viewerToolData.camera; coincident: Assembly; planeSel: Selection; DrawLatestPlane: PROC [dc: Imager.Context] = { SVSelections.ComplementReferentDC[dc, planeSel, viewerToolData]; -- erase the Jack if any SVSelections.ComplementSelectionDC[dc, planeSel, viewerToolData]; -- draw selection instead. }; SELECT skitterMode FROM surface => { skitterAssem: Assembly; [skitterAssem,----,----] _ SVSelections.GetSkitterData[]; planeSel _ SVSelections.CreatePlaneSelection[skitterAssem, viewerToolData]; SVSelections.PushPlane[planeSel]; }; tightrope => { coincident _ SVSelections.AddFloaterFromSkitter[]; SVViewerUser.ComplementAssembly[viewerToolData, coincident]; -- Draw the floater planeSel _ SVSelections.CreatePlaneSelection[coincident, viewerToolData]; SVSelections.PushPlane[planeSel]; }; coordframe => { [coincident,----,----] _ SVSelections.GetSkitterData[]; planeSel _ SVSelections.CreatePlaneSelection[coincident, viewerToolData]; SVSelections.PushPlane[planeSel]; }; ENDCASE => ERROR; ComplementSkitter[]; SVSelections.KillSkitter[viewerToolData.editToolData]; SVViewerUser.Painter[DrawLatestPlane, viewerToolData]; }; << >> MoveToTarget: PROC [viewerToolData: ViewerToolData] = { <> source: Assembly; dockCS: CoordSystem; moveeSel, targetSel: Selection; relativeMat: Matrix4by4; editToolData: EditToolData _ viewerToolData.editToolData; scene: Scene _ viewerToolData.scene; moveeSel _ SVSelections.TopMovee[]; IF moveeSel = NIL THEN RETURN; targetSel _ SVSelections.TopTarget[]; IF targetSel = NIL THEN RETURN; IF moveeSel.viewerToolData # targetSel.viewerToolData THEN { SVError.Append["Move from viewer to viewer not yet implemented.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; dockCS _ targetSel.coincident.coordSys; [----, relativeMat] _ ParentAndPosition[moveeSel, targetSel, scene]; SELECT moveeSel.referentType FROM hook => { source _ moveeSel.indirect; SVTransforms.TugTransfLeaveTug[source.coordSys, moveeSel.coincident.coordSys, dockCS, relativeMat]; }; coordSys => { source _ moveeSel.coincident; SVTransforms.AbsTransf[source.coordSys, dockCS, relativeMat]; }; ENDCASE => ERROR; SVSelections.ClearMoveeStack[editToolData]; SVSelections.ClearTargetStack[editToolData]; SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; <> }; SourceRotX: PROC [degrees: REAL] = { sourceSel: Selection; scene: Scene; viewerToolData: ViewerToolData; editToolData: EditToolData; jack, indirect: Assembly; sourceSel _ SVSelections.TopMovee[]; IF sourceSel = NIL THEN RETURN; viewerToolData _ sourceSel.viewerToolData; editToolData _ viewerToolData.editToolData; SELECT sourceSel.referentType FROM hook => { jack _ sourceSel.coincident; indirect _ sourceSel.indirect; }; coordSys => { jack _ sourceSel.coincident; indirect _ sourceSel.coincident; }; ENDCASE => ERROR; scene _ viewerToolData.scene; SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, indirect]; SVTransforms.XRotate[indirect.coordSys, jack.coordSys, degrees, TRUE]; SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, indirect]; }; SourceRotY: PROC [degrees: REAL] = { sourceSel: Selection; scene: Scene; viewerToolData: ViewerToolData; editToolData: EditToolData; jack, indirect: Assembly; sourceSel _ SVSelections.TopMovee[]; IF sourceSel = NIL THEN RETURN; viewerToolData _ sourceSel.viewerToolData; editToolData _ viewerToolData.editToolData; SELECT sourceSel.referentType FROM hook => { jack _ sourceSel.coincident; indirect _ sourceSel.indirect; }; coordSys => { jack _ sourceSel.coincident; indirect _ sourceSel.coincident; }; ENDCASE => ERROR; scene _ viewerToolData.scene; SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, indirect]; SVTransforms.YRotate[indirect.coordSys, jack.coordSys, degrees, TRUE]; SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, indirect]; }; SourceRotZ: PROC [degrees: REAL] = { sourceSel: Selection; scene: Scene; viewerToolData: ViewerToolData; editToolData: EditToolData; jack, indirect: Assembly; sourceSel _ SVSelections.TopMovee[]; IF sourceSel = NIL THEN RETURN; viewerToolData _ sourceSel.viewerToolData; editToolData _ viewerToolData.editToolData; SELECT sourceSel.referentType FROM hook => { jack _ sourceSel.coincident; indirect _ sourceSel.indirect; }; coordSys => { jack _ sourceSel.coincident; indirect _ sourceSel.coincident; }; ENDCASE => ERROR; scene _ viewerToolData.scene; SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, indirect]; SVTransforms.ZRotate[indirect.coordSys, jack.coordSys, degrees, TRUE]; SVEditUser.PaintAssemblyAllViewers[SVViewerUser.DrawAssemblyXOR, editToolData, scene, indirect]; }; CopyToAllTargets: PROC [viewerToolData: ViewerToolData] = { <> moveeCopy, moveeOriginal, parent, moveeParent: Assembly; moveeSel: Selection; editToolData: EditToolData _ viewerToolData.editToolData; oldScene, newScene: Scene; dockCS: CoordSystem; relativeMat: Matrix4by4; targets: SelectionGenerator; targetsExist: BOOL; moveeSel _ SVSelections.TopMovee[]; IF moveeSel = NIL THEN RETURN; oldScene _ moveeSel.viewerToolData.scene; SELECT moveeSel.referentType FROM hook => moveeOriginal _ moveeSel.indirect; coordSys => moveeOriginal _ moveeSel.coincident; ENDCASE => ERROR; [----, moveeParent] _ SVScene.FindAssemblyFromName[moveeOriginal.name, oldScene]; IF moveeParent = NIL THEN moveeParent _ moveeOriginal; <> [targets, targetsExist] _ SVSelections.GetSelectionGenerator[target]; IF NOT targetsExist THEN { SVError.Append["Please make some targets to copy to.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; FOR targetSel: Selection _ SVSelections.NextSelection[targets], SVSelections.NextSelection[targets] UNTIL targetSel = NIL DO newScene _ targetSel.viewerToolData.scene; IF newScene = oldScene THEN { parent _ moveeParent; [----, relativeMat] _ ParentAndPosition[moveeSel, targetSel, newScene]; } ELSE [parent, relativeMat] _ ParentAndPosition[moveeSel, targetSel, newScene]; dockCS _ targetSel.coincident.coordSys; moveeCopy _ SVScene.CopyAssemblyAndSonsUniqueNames[moveeOriginal, oldScene, newScene, parent]; SVTransforms.Normalize[moveeCopy.coordSys, moveeOriginal.coordSys]; SELECT moveeSel.referentType FROM hook => SVTransforms.TugTransfLeaveTug[moveeCopy.coordSys, moveeSel.coincident.coordSys, dockCS, relativeMat]; coordSys => SVTransforms.AbsTransf[moveeCopy.coordSys, dockCS, relativeMat]; ENDCASE => ERROR; ENDLOOP; SVSelections.ClearTargetStack[editToolData]; SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, newScene]; <> }; CopyRotate: PROC [] = { <> copy, moveeOriginal, moveeParent: Assembly; sourceSel, planeSel: Selection; viewerToolData: ViewerToolData; planeAssem: Assembly; sourceCS, planeCS: CoordSystem; editToolData: EditToolData; scene: Scene; numberOfCopies: NAT; numberOfCopiesReal: REAL; degrees, deltaDegrees, realI: REAL; toolData: ToolData; sourceSel _ SVSelections.PopMovee[]; IF sourceSel = NIL THEN RETURN; planeSel _ SVSelections.PopPlane[]; IF planeSel = NIL THEN RETURN; planeAssem _ planeSel.coincident; IF planeAssem.toolMasterObject = NIL OR planeAssem.toolMasterObject.mainBody = NIL THEN ERROR; toolData _ NARROW[planeAssem.toolMasterObject.mainBody]; IF sourceSel.viewerToolData # planeSel.viewerToolData THEN { SVError.Append["Can't copy rotate between viewers.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; viewerToolData _ sourceSel.viewerToolData; scene _ viewerToolData.scene; editToolData _ viewerToolData.editToolData; sourceCS _ sourceSel.coincident.coordSys; planeCS _ planeSel.coincident.coordSys; numberOfCopies _ SVViewerTools.GetNat[viewerToolData.textSection.xyz]; numberOfCopiesReal _ numberOfCopies; SELECT sourceSel.referentType FROM hook => moveeOriginal _ sourceSel.indirect; coordSys => moveeOriginal _ sourceSel.coincident; ENDCASE => ERROR; [----, moveeParent] _ SVScene.FindAssemblyFromName[moveeOriginal.name, scene]; deltaDegrees _ 360/numberOfCopiesReal; FOR i: NAT IN [1..numberOfCopies-1] DO realI _ i; degrees _ i*deltaDegrees; copy _ SVScene.CopyAssemblyAndSonsUniqueNames[moveeOriginal, scene, scene, moveeParent]; SVTransforms.Normalize[copy.coordSys, moveeOriginal.coordSys]; SELECT toolData.plane FROM 1 => SVTransforms.XRotate[copy.coordSys, planeCS, degrees]; 2 => SVTransforms.YRotate[copy.coordSys, planeCS, degrees]; 3, 4 => SVTransforms.ZRotate[copy.coordSys, planeCS, degrees]; ENDCASE => ERROR; ENDLOOP; SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; <> }; -- end of CopyRotate <<>> CopyToAllTargetsTree: PROC [viewerToolData: ViewerToolData] = { <> moveeCopy, moveeOriginal, parent, moveeParent: Assembly; moveeSel: Selection; editToolData: EditToolData _ viewerToolData.editToolData; oldScene, newScene: Scene; dockCS: CoordSystem; relativeMat: Matrix4by4; targets: SelectionGenerator; targetsExist: BOOL; moveeSel _ SVSelections.TopMovee[]; IF moveeSel = NIL THEN RETURN; oldScene _ moveeSel.viewerToolData.scene; SELECT moveeSel.referentType FROM hook => moveeOriginal _ moveeSel.indirect; coordSys => moveeOriginal _ moveeSel.coincident; ENDCASE => ERROR; [----, moveeParent] _ SVScene.FindAssemblyFromName[moveeOriginal.name, oldScene]; [targets, targetsExist] _ SVSelections.GetSelectionGenerator[target]; IF NOT targetsExist THEN { SVError.Append["Please make some targets to copy to.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; FOR targetSel: Selection _ SVSelections.NextSelection[targets], SVSelections.NextSelection[targets] UNTIL targetSel = NIL DO newScene _ targetSel.viewerToolData.scene; [parent, relativeMat] _ ParentAndPosition[moveeSel, targetSel, newScene]; dockCS _ targetSel.coincident.coordSys; moveeCopy _ SVScene.CopyAssemblyAndSonsUniqueNames[moveeOriginal, oldScene, newScene, parent]; SVTransforms.Normalize[moveeCopy.coordSys, moveeOriginal.coordSys]; SELECT moveeSel.referentType FROM hook => SVTransforms.TugTransfLeaveTug[moveeCopy.coordSys, moveeSel.coincident.coordSys, dockCS, relativeMat]; coordSys => SVTransforms.AbsTransf[moveeCopy.coordSys, dockCS, relativeMat]; ENDCASE => ERROR; ENDLOOP; SVSelections.ClearTargetStack[editToolData]; SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, newScene]; <> }; <<>> ParentAndPosition: PRIVATE PROC [moveeSel, targetSel: Selection, newScene: Scene] RETURNS [parent: Assembly, relativeMat: Matrix4by4] = { target: Assembly; SELECT targetSel.referentType FROM hook => { [target, parent] _ SVScene.FindAssemblyFromName[targetSel.indirect.name, newScene]; IF target # targetSel.indirect THEN ERROR; SELECT moveeSel.referentType FROM hook => relativeMat _ Matrix3d.MakeRotateYMat[180]; -- mushroom placement coordSys => relativeMat _ Matrix3d.Identity[]; -- antenae placement ENDCASE => ERROR; }; coordSys => { [target, parent] _ SVScene.FindAssemblyFromName[targetSel.coincident.name, newScene]; IF Rope.Equal[targetSel.coincident.name, "sceneAssembly", TRUE] THEN parent _ targetSel.coincident; IF target # targetSel.coincident THEN ERROR; SELECT moveeSel.referentType FROM hook => relativeMat _ Matrix3d.Identity[]; -- will think about this some more. coordSys => relativeMat _ Matrix3d.Identity[]; ENDCASE => ERROR; }; ENDCASE => ERROR; }; RandomAngle: PRIVATE PROC [] RETURNS [degrees: REAL] = { <> randomNat: NAT _ Random.ChooseInt[NIL, 0, 9999]; degrees _ (randomNat/10000.0)*360.0; }; RandomScalar: PRIVATE PROC [min, max: REAL] RETURNS [scalar: REAL] = { <> randomNat: NAT _ Random.ChooseInt[NIL, 0, 9999]; scalar _ (randomNat/10000.0)*(max-min)+min; }; CopyRandomToAllTargets: PUBLIC PROC [viewerToolData: ViewerToolData] = { <> moveeCopy, moveeOriginal, parent, moveeParent: Assembly; moveeSel: Selection; editToolData: EditToolData _ viewerToolData.editToolData; oldScene, newScene: Scene; dockCS: CoordSystem; relativeMat: Matrix4by4; targets: SelectionGenerator; targetsExist: BOOL; min, max, randomScalar, randomDegrees: REAL; moveeSel _ SVSelections.TopMovee[]; IF moveeSel = NIL THEN RETURN; oldScene _ moveeSel.viewerToolData.scene; [min, max, ----] _ SVViewerTools.GetThreeReals[editToolData.transformSection.scaleXYZ]; SELECT moveeSel.referentType FROM hook => moveeOriginal _ moveeSel.indirect; coordSys => moveeOriginal _ moveeSel.coincident; ENDCASE => ERROR; [----, moveeParent] _ SVScene.FindAssemblyFromName[moveeOriginal.name, oldScene]; [targets, targetsExist] _ SVSelections.GetSelectionGenerator[target]; IF NOT targetsExist THEN { SVError.Append["Please make some targets to copy to.", TRUE, TRUE]; SVError.Blink[]; RETURN; }; FOR targetSel: Selection _ SVSelections.NextSelection[targets], SVSelections.NextSelection[targets] UNTIL targetSel = NIL DO newScene _ targetSel.viewerToolData.scene; IF newScene = oldScene THEN { parent _ moveeParent; [----, relativeMat] _ ParentAndPosition[moveeSel, targetSel, newScene]; } ELSE [parent, relativeMat] _ ParentAndPosition[moveeSel, targetSel, newScene]; dockCS _ targetSel.coincident.coordSys; moveeCopy _ SVScene.CopyAssemblyAndSonsUniqueNames[moveeOriginal, oldScene, newScene, parent]; SELECT moveeSel.referentType FROM hook => SVTransforms.TugTransfLeaveTug[moveeCopy.coordSys, moveeSel.coincident.coordSys, dockCS, relativeMat]; coordSys => SVTransforms.AbsTransf[moveeCopy.coordSys, dockCS, relativeMat]; ENDCASE => ERROR; randomDegrees _ RandomAngle[]; randomScalar _ RandomScalar[min, max]; SVTransforms.ZRotate[moveeCopy.coordSys, dockCS, randomDegrees]; SVTransforms.ScaleEven[moveeCopy, dockCS, randomScalar]; ENDLOOP; SVSelections.ClearTargetStack[editToolData]; SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, newScene]; <> }; <> <> <> <> <> <<};>> <> <<};>> ExtendCurrent: PUBLIC PROC [viewerToolData: ViewerToolData] = TRUSTED { <> editToolData: EditToolData; scene: Scene; assembly, parent: Assembly; prim: Primitive; assemblyName: Rope.ROPE; success: BOOL; editToolData _ viewerToolData.editToolData; scene _ viewerToolData.scene; [assembly, prim, viewerToolData] _ SVSelections.GetSkitterData[]; IF assembly = NIL THEN RETURN; assemblyName _ assembly.name; [assembly, parent, success] _ SVEditUser.FindAssemblyFromName[assemblyName, scene]; IF NOT success THEN { SVError.Append[Rope.Cat["ExtendCurrent: assembly ", assemblyName, " not found."], TRUE, TRUE]; SVError.Blink[]; RETURN; }; SVSelections.UpdateSkitter[parent, prim, viewerToolData]; }; ParentOfSkitter: PROC [] = TRUSTED { <> viewerToolData: ViewerToolData; editToolData: EditToolData; scene: Scene; assembly, realAssembly, parent: Assembly; prim: Primitive; [realAssembly, prim, viewerToolData] _ SVSelections.GetSkitterData[]; editToolData _ viewerToolData.editToolData; scene _ viewerToolData.scene; IF realAssembly = NIL THEN RETURN; [assembly, parent] _ SVScene.FindAssemblyFromName[realAssembly.name, scene]; IF assembly # realAssembly THEN ERROR; IF parent#NIL THEN SVSelections.UpdateSkitter[parent, prim, viewerToolData]; }; SetTool: PUBLIC PROC = TRUSTED { <> editToolData: EditToolData; viewerToolData: ViewerToolData; planeAssem: Assembly; planeSel: Selection; scene: Scene; planeSel _ SVSelections.TopPlane[]; IF planeSel = NIL THEN { SVError.Append["SetTool: Make a plane selection first", TRUE, TRUE]; SVError.Blink[]; RETURN; }; planeAssem _ planeSel.coincident; viewerToolData _ planeSel.viewerToolData; scene _ viewerToolData.scene; editToolData _ NARROW[viewerToolData.editToolData]; planeAssem.showAs _ tool; SVScene.AddOrResizeToolToAssembly[planeAssem, scene]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; }; -- end of SetTool ResetTool: PUBLIC PROC = TRUSTED { <> editToolData: EditToolData; viewerToolData: ViewerToolData; planeAssem: Assembly; planeSel: Selection; scene: Scene; planeSel _ SVSelections.TopPlane[]; IF planeSel = NIL THEN { SVError.Append["ResetTool: Make a plane selection first", TRUE, TRUE]; SVError.Blink[]; RETURN; }; planeAssem _ planeSel.coincident; viewerToolData _ planeSel.viewerToolData; scene _ viewerToolData.scene; editToolData _ NARROW[viewerToolData.editToolData]; planeAssem.showAs _ normal; SVEditUser.SceneNewVersion[viewerToolData]; SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; }; CycleTool: PUBLIC PROC = TRUSTED { <> editToolData: EditToolData; viewerToolData: ViewerToolData; planeAssem: Assembly; planeSel: Selection; scene: Scene; camera: Camera; toolData: ToolData; DrawNewPlane: PROC [dc: Imager.Context] = { SVSelections.ComplementSelectionDC[dc, planeSel, viewerToolData]; }; planeSel _ SVSelections.TopPlane[]; IF planeSel = NIL THEN { SVError.Append["CycleTool: Make a plane selection first", TRUE, TRUE]; SVError.Blink[]; RETURN; }; planeAssem _ planeSel.coincident; viewerToolData _ planeSel.viewerToolData; camera _ viewerToolData.camera; scene _ viewerToolData.scene; editToolData _ NARROW[viewerToolData.editToolData]; IF planeAssem.toolMasterObject = NIL OR planeAssem.toolMasterObject.mainBody = NIL THEN SVScene.AddOrResizeToolToAssembly[planeAssem, scene]; toolData _ NARROW[planeAssem.toolMasterObject.mainBody]; SVViewerUser.Painter[DrawNewPlane, viewerToolData]; toolData.plane _ IF toolData.plane = 3 THEN 1 ELSE toolData.plane + 1; SVViewerUser.Painter[DrawNewPlane, viewerToolData]; <> SELECT toolData.plane FROM 1 => SVError.Append[Rope.Cat["x = 0 plane of ", planeAssem.name, " now selected."], TRUE, TRUE]; 2 => SVError.Append[Rope.Cat["y = 0 plane of ", planeAssem.name, " now selected."], TRUE, TRUE]; 3 => SVError.Append[Rope.Cat["z = 0 plane of ", planeAssem.name, " now selected."], TRUE, TRUE]; <<4 => SVError.Append[Rope.Cat["All planes of ", planeAssem.name, " now selected."], TRUE, TRUE];>> ENDCASE => ERROR; IF planeAssem.showAs = tool OR planeAssem.showAs = both THEN SVEditUser.PaintSceneAllViewers[SVViewerUser.EraseAndDrawSceneEtc, editToolData, scene]; }; DropPerpendicular: PROC = TRUSTED { sourceSel, planeSel: Selection; toolData: ToolData; planeAssem: Assembly; scene: Scene; camera: Camera; viewerToolData: ViewerToolData; selectionMat, sourcePlane: Matrix4by4; interceptPlane, originPlane: Point3d; sourceSel _ SVSelections.TopMovee[]; IF sourceSel = NIL THEN RETURN; planeSel _ SVSelections.TopPlane[]; IF planeSel = NIL THEN RETURN; planeAssem _ planeSel.coincident; viewerToolData _ planeSel.viewerToolData; camera _ viewerToolData.camera; scene _ viewerToolData.scene; IF planeAssem.toolMasterObject = NIL OR planeAssem.toolMasterObject.mainBody = NIL THEN SVScene.AddOrResizeToolToAssembly[planeAssem, scene]; toolData _ NARROW[planeAssem.toolMasterObject.mainBody]; sourcePlane _ CoordSys.FindAInTermsOfB[sourceSel.coincident.coordSys, planeSel.coincident.coordSys]; originPlane _ Matrix3d.OriginOfMatrix[sourcePlane]; interceptPlane _ originPlane; SELECT toolData.plane FROM 1 => interceptPlane[1] _ 0.0; 2 => interceptPlane[2] _ 0.0; 3 => interceptPlane[3] _ 0.0; <<4 => Who knows.>> ENDCASE => ERROR; SVViewerInput.ComplementSkitter[]; -- erase any old skitter selectionMat _ CoordSys.FindInTermsOfWorld[planeSel.coincident.coordSys]; selectionMat _ Matrix3d.LocalTranslate[selectionMat, interceptPlane[1], interceptPlane[2], interceptPlane[3]]; SVSelections.UpdateSkitter[NIL, NIL, viewerToolData]; SVSelections.PositionSkitter[[0,0], selectionMat]; -- update skitterWORLD SVSelections.SetModeSkitter[tightrope]; SVViewerInput.ComplementSkitter[]; -- draw new skitter SVViewerInput.SkitterMakes[]; -- sceneAssembly will be the parent of the new jack. }; END.