<?xml version="1.0"?>

<st-source>
<!-- 
Name: CADSM-UI
HideSource: false
PackageName: CADSM-UI
Parcel: #('cadsmui')
PrerequisiteParcels: #(#('CADSM-UI-DXF' '') #('CADSM-UI-STEP' '') #('CADSM-Basic' ''))
SaveSource: true
Version: 2
Date: 1:01:57 pm October 30, 2009
 -->
<time-stamp>From VisualWorks®, 7.5 of April 16, 2007 on October 30, 2009 at 1:01:57 pm</time-stamp>


<do-it>(Dialog confirm: 'You are filing-in a Parcel source file!\\While this is possible it will not have\the same effect as loading the parcel.\None of the Parcel''s prerequisites will\be loaded and none of its load actions\will be performed.\\Are you sure you want to file-in?' withCRs) ifFalse: [self error: 'Parcel file-in abandoned.  Choose terminate or close.']</do-it>

<class>
<name>DrawingInterface</name>
<environment>CADSM.UI</environment>
<super>StCAD.CADDrawingInterface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>SimpleDialog</name>
<environment>CADSM.UI</environment>
<super>UI.SimpleDialog</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>bufferTrigger adButton </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>View</name>
<environment>CADSM.UI</environment>
<super>UI.View</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUIItem</name>
<environment>CADSM.UI</environment>
<super>CADSMItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>RegistrationDialog</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.SimpleDialog</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aArray aFullName aEmail aTextEditor </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>HandleTracker</name>
<environment>CADSM.UI</environment>
<super>UI.ScrollingTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aHandle </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>ASMTextParser</name>
<environment>CADSM.UI</environment>
<super>Kernel.ExternalLanguageParser</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>level </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>ApplicationModel</name>
<environment>CADSM.UI</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>adButton </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>Editor</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>selection treeView cadView aMediator </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>Animation</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cadInterface timeSeries animationData icurrent istart iend tcurrent tstart tend speed animationProcess </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUITool</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aMediator name aIcon aCursor </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUISelectionTool</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUITool</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLRetainedMedium</name>
<environment>CADSM.UI</environment>
<super>Jun.JunOpenGLRetainedMedium</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUICreationTool</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUITool</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLDisplayController</name>
<environment>CADSM.UI</environment>
<super>Jun.JunOpenGLDisplayController</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>ToolTracker</name>
<environment>CADSM.UI</environment>
<super>UI.ScrollingTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aTool rvFirstv </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>SelectionToolTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.ToolTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>RefFrameTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.HandleTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aFrame frozenFrame rFcenterF direction rvFirstv rvOldv </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>PositionTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.RefFrameTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>TiltTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.RefFrameTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLView</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.View</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aCamera preferredBounds cHandle cachedBitmap cachedRenderingContext displayListHolder bitmapSemaphore </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<comment>
<class-id>CADSM.UI.OpenGLView</class-id>
<body>OpenGLView controls aCamera specific to itself. aEditor and aUniverse may have many views and cameras.

Instance Variables:
	aCamera	&lt;PerspectiveCamera&gt;	description of aCamera
	bitmapSemaphore	&lt;Semaphore&gt;	description of bitmapSemaphore
	cachedBitmap	&lt;OpenGLRetainedMedium&gt;	description of cachedBitmap
	cachedRenderingContext	&lt;JunOpenGLRenderingContext&gt;	description of cachedRenderingContext
	displayListHolder	&lt;ValueHolder&gt;	description of displayListHolder
	preferredBounds	&lt;Object&gt;	description of preferredBounds

</body>
</comment>

<class>
<name>CADSMUIMediator</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>eventHandlers aEditor aGeoUniverse aMbDUniverse aTool cSelectedItem cHandle cMemento aSketch aProcess aTextCollector aFilename isDirty </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUIAlibreDesign</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<comment>
<class-id>CADSM.UI.CADSMUIAlibreDesign</class-id>
<body>This class does all the unique operations of AlibreDesign.</body>
</comment>

<class>
<name>CADSMUIZoomInTool</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUITool</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUIOpenGLImage</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aCPointer aImage </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUISelectionSet</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aOrderedSet </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>RotateTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.RefFrameTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>Handle</name>
<environment>CADSM.UI</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aView originPx image aSpatialItem </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>UniverseHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.Handle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>RotateHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.Handle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>RotateUniverseHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.UniverseHandle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>PositionUniverseHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.UniverseHandle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>PositionHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.Handle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>TiltHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.Handle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>ZoomInToolTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.ToolTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>TiltUniverseHandle</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.UniverseHandle</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMtoCOM</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aAssembly aWorldFrame aTextCollector aMbDSystem mbdUnits mbdProcess aCADSMAlibre pauseAfterOutput criticalSectionSemaphore </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLRenderingContext</name>
<environment>CADSM.UI</environment>
<super>Jun.JunOpenGLRenderingContext</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>modelviewCPointer projectionCPointer viewportCPointer cDoubleCPointer </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLPickingRenderingContext</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.OpenGLRenderingContext</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>selectionBufferSize </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLSolidRenderingContext</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.OpenGLRenderingContext</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLWireframeRenderingContext</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.OpenGLRenderingContext</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>OpenGLHiddenLineRenderingContext</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.OpenGLRenderingContext</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-App</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CreationToolTracker</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.ToolTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<class>
<name>CADSMUITreeNode</name>
<environment>CADSM.UI</environment>
<super>CADSM.UI.CADSMUIItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>geoItem children displayString </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-UI-Basic</category>
<attributes>
<package>CADSM-UI</package>
</attributes>
</class>

<comment>
<class-id>CADSM.UI.CADSMUITreeNode</class-id>
<body>TreeNode is for the tree view in CADSM.
To do:
Move it to subclass of SupItem.</body>
</comment>

<shared-variable>
<name>InstallDate</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>Keys1</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>ProductID</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>CADSM.UI.RegistrationDialog aStringID</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>RegistrationDate</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>Keys2</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>QuitRequired</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>false</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>SaveRequired</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>false</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>PatchID</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>FullName</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>LastUsed</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>RegistrationOK</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>false</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>JustSnapped</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>false</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>HardwareID</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>Email</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>SupportExpirationDate</name>
<environment>CADSM.UI.RegistrationDialog</environment>
<private>false</private>
<constant>false</constant>
<category>variables</category>
<initializer>nil</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<shared-variable>
<name>NameToGEOdict</name>
<environment>CADSM.UI.ASMTextParser</environment>
<private>false</private>
<constant>false</constant>
<category>dictionary</category>
<initializer>CADSM.UI.ASMTextParser initialize</initializer>
<attributes>
<package>CADSM-UI</package>
</attributes>
</shared-variable>

<methods>
<class-id>CADSM.UI.DrawingInterface</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="boundingBox">boundingBox
	| answer |
	answer := worldFrame boundingBox.
	geoRootItem notNil ifTrue: [answer merge: geoRootItem boundingBox].
	^answer</body>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	worldFrame renderOn: aRenderingContext.
	geoRootItem notNil ifTrue: [geoRootItem renderOn: aRenderingContext]</body>
</methods>

<methods>
<class-id>CADSM.UI.DrawingInterface</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	palette := nil.
	selections := OrderedCollection new.
	handles := OrderedCollection new.
	drawing := self class drawingClass new.
	drawing container: self.
	display := nil.
	hideHandles := 0.
	memento := Polymorphic.GFBoundedStack bound: 15.
	selectedGEOs := StCAD.StGeo.GEOSelections new.
	worldFrame := StCAD.StGeo.GEOWorldFrame2 new.
	worldFrame refFrame: self.
	worldFrame fixedAtRef.
	projectionFrame := nil</body>
</methods>

<methods>
<class-id>CADSM.UI.DrawingInterface</class-id> <category>handles</category>

<body package="CADSM-UI" selector="hideHandles">hideHandles
	"Do nothing for now."</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="adaptorFor:">adaptorFor: aspect 
	^(AspectAdaptor subjectChannel: self subject)
		forAspect: aspect</body>

<body package="CADSM-UI" selector="bufferedAdaptorFor:">bufferedAdaptorFor: aspect 
	| adaptor |
	adaptor := (AspectAdaptor subjectChannel: self subject)
				forAspect: aspect.
	^BufferedValueHolder subject: adaptor triggerChannel: bufferTrigger</body>

<body package="CADSM-UI" selector="bufferedAdaptorForIndex:">bufferedAdaptorForIndex: i 
	| adaptor |
	adaptor := (IndexedAdaptor subjectChannel: self subject)
				forIndex: i.
	^BufferedValueHolder subject: adaptor triggerChannel: bufferTrigger</body>

<body package="CADSM-UI" selector="closeAccept">closeAccept
	bufferTrigger value: true.
	super closeAccept</body>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	adButton := StCAD.StDoc.AdButton new.
	escapeIsCancel := false.
	bufferTrigger := false asValue</body>

<body package="CADSM-UI" selector="reset">reset
	bufferTrigger value: false</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="bufferTrigger">bufferTrigger
	^bufferTrigger</body>

<body package="CADSM-UI" selector="subject">subject
	^self subclassResponsibility</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog</class-id> <category>validation</category>

<body package="CADSM-UI" selector="validateDouble:">validateDouble: aController 
	| array |
	array := #(-1.0d100 #&lt; #double #&lt; 1.0d100) copy.
	array at: 3 put: aController.
	^self validateDoubleWithArguments: array</body>

<body package="CADSM-UI" selector="validateDoubleGreaterThanZero:">validateDoubleGreaterThanZero: aController 
	| array |
	array := #(0.0d #&lt; #double #&lt; 1.0d100) copy.
	array at: 3 put: aController.
	^self validateDoubleWithArguments: array</body>

<body package="CADSM-UI" selector="validateDoubleWithArguments:">validateDoubleWithArguments: array 
	| lowerLimit lowerOp aController upperOp upperLimit entry |
	lowerLimit := array at: 1.
	lowerOp := array at: 2.
	aController := array at: 3.
	upperOp := array at: 4.
	upperLimit := array at: 5.
	(aController hasEditValue
		and: 
			[entry := aController editValue.
			entry isKindOf: Number])
		ifTrue: 
			[entry := entry asPrettyDouble.
			aController selectEntireText; deselect; replaceSelectionWith: entry printString; select]
		ifFalse: 
			[aController selectEntireText.
			Dialog warn: 'Enter a number like -5 or -5.5 or -55.555d-55.'.
			^false].
	(lowerLimit perform: lowerOp with: entry)
		&amp; (entry perform: upperOp with: upperLimit)
		ifFalse: 
			[aController selectEntireText.
			Dialog warn: ('Enter a number such that &lt;n&gt;&lt;1p&gt; &lt;2s&gt; number &lt;4s&gt; &lt;5p&gt; ' expandMacrosWithArguments: array).
			^false].
	^true</body>

<body package="CADSM-UI" selector="validateDoubleZeroAndGreater:">validateDoubleZeroAndGreater: aController 
	| array |
	array := #(0.0d #&lt;= #double #&lt; 1.0d100) copy.
	array at: 3 put: aController.
	^self validateDoubleWithArguments: array</body>

<body package="CADSM-UI" selector="validateIntegerWithArguments:">validateIntegerWithArguments: array 
	| lowerLimit lowerOp aController upperOp upperLimit entry |
	lowerLimit := array at: 1.
	lowerOp := array at: 2.
	aController := array at: 3.
	upperOp := array at: 4.
	upperLimit := array at: 5.
	(aController hasEditValue
		and: 
			[entry := aController editValue.
			entry isInteger])
		ifFalse: 
			[Dialog warn: 'Enter an integer.'.
			^false].
	(lowerLimit perform: lowerOp with: entry)
		&amp; (entry perform: upperOp with: upperLimit)
		ifFalse: 
			[Dialog warn: 'Enter an integer such that ' , lowerLimit printString , ' ' , lowerOp , ' integer ' , upperOp , ' ' , upperLimit printString , '.'.
			^false].
	^true</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog</class-id> <category>ad</category>

<body package="CADSM-UI" selector="adButton">adButton
	^adButton</body>

<body package="CADSM-UI" selector="changeAdxxxBy32">changeAdxxxBy32
	adButton changeAdxxxBy32</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog</class-id> <category>binding</category>

<body package="CADSM-UI" selector="labelFor:">labelFor: aKey 
	"Return an instance of a non-abstract subclass of CharacterArray, 
	that will be used as a label for a widget. Check the label registry 
	if no implementation has been provided."

	^[self perform: aKey]
		on: self application messageNotUnderstoodSignal
		do: 
			[:ex | 
			| sel |
			sel := ex parameter selector.
			sel == aKey
				ifTrue: [ex return: (self application labelFor: aKey)]
				ifFalse: [ex pass]]</body>

<body package="CADSM-UI" selector="visualFor:">visualFor: aKey 
	"Return an instance of any non-abstract subclass of 
	VisualComponent (in practice usually either ComposedText or 
	Image) for use as a label for a widget."

	^[self perform: aKey]
		on: self application messageNotUnderstoodSignal
		do: 
			[:ex | 
			| sel |
			sel := ex parameter selector.
			sel == aKey
				ifTrue: [ex return: (self application visualFor: aKey)]
				ifFalse: [ex pass]]</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog</class-id> <category>private</category>

<body package="CADSM-UI" selector="openExplainFile:label:">openExplainFile: aFilename label: labelString 
	| filepath newLabelString |
	filepath := (Filename fromComponents: #('resource' 'explain'))
				construct: aFilename.
	newLabelString := labelString , '                ' , StCAD.StDoc.AdData adTitle title.
	[self openReadOnlyFile: filepath label: newLabelString]
		on: OsInaccessibleError
		do: 
			[:ex | 
			| dirString |
			dirString := (Filename fromComponents: #('resource' 'explain')) asString.
			Dialog warn: ('All Explain files (*.sdoc) should be in the subsubdirectory ''&lt; 1s &gt;''. &lt;n&gt;When unzipping freecad*.zip and patch*.zip make sure that subdirectory information are preserved. &lt;n&gt;Otherwise, create subsubdirectory ''&lt; 1s &gt;'' and move all *.sdoc into it.' expandMacrosWith: dirString)]</body>

<body package="CADSM-UI" selector="openReadOnlyFile:label:">openReadOnlyFile: aFilename label: labelString 
	StCAD.StDoc.EditorDialog new
		filename: aFilename
		readOnly: true
		label: labelString</body>
</methods>

<methods>
<class-id>CADSM.UI.SimpleDialog class</class-id> <category>instance creation</category>

<body package="CADSM-UI" selector="openOn:">openOn: object 
	| newDialog |
	newDialog := super new.
	newDialog subject value: object.
	^newDialog openInterface</body>

<body package="CADSM-UI" selector="openOn:withSpec:">openOn: object withSpec: aSymbol 
	| newDialog |
	newDialog := super new.
	newDialog subject value: object.
	^newDialog openInterface: aSymbol</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	aArray := nil asValue.
	aFullName := self bufferedAdaptorForIndex: 1.
	aEmail := self bufferedAdaptorForIndex: 2</body>

<body package="CADSM-UI" selector="subject">subject
	^aArray</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aEmail">aEmail
	^aEmail</body>

<body package="CADSM-UI" selector="aEmail:">aEmail: anObject
	aEmail := anObject</body>

<body package="CADSM-UI" selector="aFullName">aFullName
	^aFullName</body>

<body package="CADSM-UI" selector="aFullName:">aFullName: anObject
	aFullName := anObject</body>

<body package="CADSM-UI" selector="aTextEditor">aTextEditor
	"This method was generated by UIDefiner.  Any edits made here
	may be lost whenever methods are automatically defined.  The
	initialization provided below may have been preempted by an
	initialize method."

	^aTextEditor isNil
		ifTrue:
			[aTextEditor := String new asValue]
		ifFalse:
			[aTextEditor]</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog class</class-id> <category>instance creation</category>

<body package="CADSM-UI" selector="openOn:text:">openOn: object text: aText 
	| newDialog |
	newDialog := super new.
	newDialog subject value: object.
	newDialog aTextEditor value: aText.
	^newDialog openInterface</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog class</class-id> <category>examples</category>

<body package="CADSM-UI" selector="example1">example1
	"self example1"

	| nByte aRSALengthLimit nBit aKeyGenClass aKeyGen1 aKeyGen2 aFullName aEmail aInstallDate aRegistrationDate aSupportExpirationDate aKeys1 aKeys2 cItem cA aRSAPublicKey cE aRSAPrivateKey cD |
	nByte := 64.
	aRSALengthLimit := nByte - 11.
	nBit := nByte * 8.
	aKeyGenClass := Security.RSAKeyGenerator.
	aKeyGen1 := aKeyGenClass keySize: nBit.
	aKeyGen2 := aKeyGenClass keySize: nBit.
	aFullName := 'Aik-Siong Koh'.
	aEmail := 'askoh@askoh.com'.
	aInstallDate := Date today.
	aRegistrationDate := Date today addDays: 30.
	aSupportExpirationDate := aRegistrationDate addYears: 1.
	aKeys1 := Array with: aKeyGen1 publicKey with: aKeyGen1 privateKey.
	aKeys2 := Array with: aKeyGen2 publicKey with: aKeyGen2 privateKey.
	cItem := (OrderedCollection new: 10)
				add: aFullName;
				add: aEmail;
				add: aInstallDate;
				add: aRegistrationDate;
				add: aSupportExpirationDate;
				add: aKeys1;
				add: aKeys2;
				yourself.
	"StoreOn format."
	cA := cItem collect: 
					[:item | 
					| wStream |
					wStream := (String new: 1000) writeStream.
					item storeOn: wStream.
					wStream contents].

	"Encrypt info."
	aRSAPublicKey := aKeyGen1 publicKey.
	cE := cA collect: 
					[:string | 
					| paddedString |
					paddedString := (string breakIntoSizeOf: aRSALengthLimit
								padWith: Character space) concatenateCollections.
					(Security.RSA new)
						publicKey: aRSAPublicKey;
						encryptLong: paddedString asByteArray].

	"Decrypt info."
	aRSAPrivateKey := aKeyGen1 privateKey.
	cD := cE collect: 
					[:aByteArray | 
					((Security.RSA new)
						privateKey: aRSAPrivateKey;
						decryptLong: aByteArray) asByteString].
	"Test for correctness."
	cA with: cD
		parallelDo: 
			[:a :d | 
			(Compiler evaluate: a) = (Compiler evaluate: d) ifFalse: [self halt]]</body>

<body package="CADSM-UI" selector="example2">example2
	"RegistrationDialog example2."

	"Testing dialog."

	| dummy dialogResponse |
	self toTranscriptShow: 'RegistrationDialog class example1.'.
	dummy := Array with: nil with: nil.
	self toTranscriptShow: dummy.
	dialogResponse := RegistrationDialog openOn: dummy text: 'This is a test.'.
	self toTranscriptShow: dialogResponse.
	self toTranscriptShow: dummy</body>

<body package="CADSM-UI" selector="example3">example3
	"RegistrationDialog example3."

	"Generate Keys3."

	| nByte nBit aKeyGen block filepath bos |
	nByte := 64.
	nBit := nByte * 8.
	aKeyGen := Security.RSAKeyGenerator keySize: nBit.
	block := 
			[:string :key | 
			filepath := (Filename fromComponents: #('resource')) construct: string.
			filepath asFilename definitelyExists 
				ifTrue: [self error: ('Do not overwrite &lt;1s&gt;.' expandMacrosWith: filepath)].
			bos := BinaryObjectStorage onNew: filepath asFilename writeStream.
			[bos nextPut: key] ensure: [bos close]].
	block value: 'publickey.bos' value: aKeyGen publicKey.
	block value: 'privatekey.bos' value: aKeyGen privateKey</body>

<body package="CADSM-UI" selector="example4">example4
	"RegistrationDialog example4."

	"Read install.bos and produce register.bos."

	| aDataRegistration aRSAPublicKey2 block data edata method filepath bos oldDate |
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'register.txt'.
	aDataRegistration := RegistrationDialog example4a.
	self toFile: filepath Show: aDataRegistration.
	aDataRegistration aProductID ifNil: [self halt].
	aDataRegistration aInstallDate ifNil: [self halt].
	aDataRegistration aFullName ifNil: [self halt].
	aDataRegistration aEmail ifNil: [self halt].
	aDataRegistration aRSAPublicKey2 ifNil: [self halt].
	aDataRegistration aRSAPrivateKey2 ifNil: [self halt].
	aDataRegistration aRegistrationDate 
		ifNil: [aDataRegistration aRegistrationDate: Timestamp now].
	aDataRegistration aSupportExpirationDate 
		ifNil: [aDataRegistration aSupportExpirationDate: (Timestamp now addYears: 1)]
		ifNotNil: 
			[oldDate := aDataRegistration aSupportExpirationDate.
			oldDate &gt; Timestamp now 
				ifTrue: [aDataRegistration aSupportExpirationDate: (oldDate addYears: 1)]
				ifFalse: 
					[aDataRegistration aSupportExpirationDate: (Timestamp now addYears: 1)]].
	self toFile: filepath Show: aDataRegistration.
	aRSAPublicKey2 := aDataRegistration aRSAPublicKey2.
	block := 
			[:symbol | 
			data := aDataRegistration perform: symbol.
			edata := self withKey: aRSAPublicKey2 Encrypt: data.
			method := (symbol , ':') asSymbol.
			aDataRegistration perform: method with: edata].
	block value: #aProductID.
	block value: #aInstallDate.
	block value: #aFullName.
	block value: #aEmail.
	block value: #aRSAPublicKey2.
	block value: #aRSAPrivateKey2.
	block value: #aRegistrationDate.
	block value: #aSupportExpirationDate.
	self toFile: filepath Show: aDataRegistration.
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'register.bos'.
	bos := BinaryObjectStorage onNew: filepath asFilename writeStream.
	[bos nextPut: aDataRegistration] ensure: [bos close]</body>

<body package="CADSM-UI" selector="example4a">example4a
	"RegistrationDialog example4a."

	"Read install.bos and decrypt it."

	| filepath bos aDataRegistration block |
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'install.bos'.
	bos := BinaryObjectStorage onOldNoScan: filepath asFilename readStream.
	[aDataRegistration := bos contents at: 1] ensure: [bos close].
	block := 
			[:symbol | 
			| data ddata method |
			data := aDataRegistration perform: symbol.
			ddata := self withKey3Decrypt: data.
			method := (symbol , ':') asSymbol.
			aDataRegistration perform: method with: ddata].
	block value: #aProductID.
	block value: #aInstallDate.
	block value: #aFullName.
	block value: #aEmail.
	block value: #aRSAPublicKey2.
	block value: #aRSAPrivateKey2.
	^aDataRegistration</body>

<body package="CADSM-UI" selector="example4b">example4b
	"RegistrationDialog example4b."

	"Read install.bos and produce a BAD register.bos."

	| aDataRegistration aRSAPublicKey3 block data edata method filepath bos oldDate |
	aDataRegistration := RegistrationDialog example4a.
	aDataRegistration aInstallDate ifNil: [self halt].
	aDataRegistration aFullName ifNil: [self halt].
	aDataRegistration aEmail ifNil: [self halt].
	aDataRegistration aRSAPublicKey2 ifNil: [self halt].
	aDataRegistration aRSAPrivateKey2 ifNil: [self halt].
	aDataRegistration aRegistrationDate 
		ifNil: [aDataRegistration aRegistrationDate: Timestamp now].
	aDataRegistration aSupportExpirationDate 
		ifNil: [aDataRegistration aSupportExpirationDate: (Timestamp now addYears: 1)]
		ifNotNil: 
			[oldDate := aDataRegistration aSupportExpirationDate.
			oldDate &gt; Timestamp now 
				ifTrue: [aDataRegistration aSupportExpirationDate: (oldDate addYears: 1)]
				ifFalse: 
					[aDataRegistration aSupportExpirationDate: (Timestamp now addYears: 1)]].
	aRSAPublicKey3 := self aRSAPublicKey3.
	block := 
			[:symbol | 
			data := aDataRegistration perform: symbol.
			edata := self withKey: aRSAPublicKey3 Encrypt: data.
			method := (symbol , ':') asSymbol.
			aDataRegistration perform: method with: edata].
	block value: #aInstallDate.
	block value: #aFullName.
	block value: #aEmail.
	block value: #aRSAPublicKey2.
	block value: #aRSAPrivateKey2.
	block value: #aRegistrationDate.
	block value: #aSupportExpirationDate.
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'register.bos'.
	bos := BinaryObjectStorage onNew: filepath asFilename writeStream.
	[bos nextPut: aDataRegistration] ensure: [bos close]</body>

<body package="CADSM-UI" selector="example5">example5
	"RegistrationDialog example5."

	"Read register.bos and produce extended register.bos."

	| aInstall aRegister newRegister oldDate aRSAPublicKey2 block data edata method filepath backupPath bos |
	aInstall := RegistrationDialog example4a.
	aRegister := RegistrationDialog example5a.
	newRegister := aRegister copy.
	newRegister aSupportExpirationDate ifNil: [self halt]
		ifNotNil: 
			[oldDate := newRegister aSupportExpirationDate.
			oldDate &gt; Timestamp now 
				ifTrue: [newRegister aSupportExpirationDate: (oldDate addYears: 1)]
				ifFalse: [newRegister aSupportExpirationDate: (Timestamp now addYears: 1)]].
	aRSAPublicKey2 := aInstall aRSAPublicKey2.
	block := 
			[:symbol | 
			data := newRegister perform: symbol.
			edata := self withKey: aRSAPublicKey2 Encrypt: data.
			method := (symbol , ':') asSymbol.
			newRegister perform: method with: edata].
	block value: #aInstallDate.
	block value: #aFullName.
	block value: #aEmail.
	block value: #aRSAPublicKey2.
	block value: #aRSAPrivateKey2.
	block value: #aRegistrationDate.
	block value: #aSupportExpirationDate.
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'register.bos'.
	backupPath := filepath asString copyReplaceAll: '.bos' with: '.bkp'.
	filepath asFilename renameTo: backupPath.
	bos := BinaryObjectStorage onNew: filepath asFilename writeStream.
	[bos nextPut: newRegister] ensure: [bos close]</body>

<body package="CADSM-UI" selector="example5a">example5a
	"RegistrationDialog example5a."

	"Read register.bos and decrypt it."

	| aInstall aRSAPrivateKey2 filepath bos aDataRegistration block data ddata method |
	aInstall := RegistrationDialog example4a.
	aRSAPrivateKey2 := aInstall aRSAPrivateKey2.
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'register.bos'.
	bos := BinaryObjectStorage onOldNoScan: filepath asFilename readStream.
	[aDataRegistration := bos contents at: 1] ensure: [bos close].
	block := 
			[:symbol | 
			data := aDataRegistration perform: symbol.
			ddata := self withKey: aRSAPrivateKey2 Decrypt: data.
			method := (symbol , ':') asSymbol.
			aDataRegistration perform: method with: ddata].
	block value: #aInstallDate.
	block value: #aFullName.
	block value: #aEmail.
	block value: #aRSAPublicKey2.
	block value: #aRSAPrivateKey2.
	block value: #aRegistrationDate.
	block value: #aSupportExpirationDate.
	^aDataRegistration</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog class</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aDisplayString">aDisplayString
	| array string |
	array := Array with: self aFullName asString with: self aEmail asString.
	string := self isRegistrationOK 
				ifTrue: [#'Full License to &lt;1s&gt; %&lt;&lt;2s&gt;%&gt;' &lt;&lt; #'CADSM.UI']
				ifFalse: [#'Evaluation License to &lt;1s&gt; %&lt;&lt;2s&gt;%&gt;' &lt;&lt; #'CADSM.UI'].
	^string expandMacrosWithArguments: array</body>

<body package="CADSM-UI" selector="aEmail">aEmail
	^Email ifNotNil: [:eEmail | self withKey1Decrypt: eEmail]</body>

<body package="CADSM-UI" selector="aEmail:">aEmail: aObject 
	Email := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aFullName">aFullName
	^FullName ifNotNil: [:eFullName | self withKey1Decrypt: eFullName]</body>

<body package="CADSM-UI" selector="aFullName:">aFullName: aObject 
	FullName := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aHardwareID">aHardwareID
	^HardwareID 
		ifNotNil: [:eHardwareID | self withKey1Decrypt: eHardwareID]</body>

<body package="CADSM-UI" selector="aHardwareID:">aHardwareID: aObject 
	HardwareID := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aInstallDate">aInstallDate
	^InstallDate 
		ifNotNil: [:eInstallDate | self withKey1Decrypt: eInstallDate]</body>

<body package="CADSM-UI" selector="aInstallDate:">aInstallDate: aObject 
	InstallDate := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aLastUsed">aLastUsed
	^LastUsed ifNotNil: [:eLastUsed | self withKey1Decrypt: eLastUsed]</body>

<body package="CADSM-UI" selector="aLastUsed:">aLastUsed: aTimeStamp 
	| aLastUsed |
	aLastUsed := self aLastUsed.
	(aLastUsed isNil or: [aLastUsed &lt; aTimeStamp]) 
		ifTrue: 
			[LastUsed := self withKey1Encrypt: aTimeStamp.
			SaveRequired := true]</body>

<body package="CADSM-UI" selector="aPatchID">aPatchID
	^PatchID 
		ifNotNil: [:ePatchID | self withKey1Decrypt: ePatchID]</body>

<body package="CADSM-UI" selector="aPatchID:">aPatchID: aObject 
	PatchID := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aProductID">aProductID
	^ProductID ifNotNil: [:eProductID | self withKey1Decrypt: eProductID]</body>

<body package="CADSM-UI" selector="aProductID:">aProductID: aObject 
	ProductID := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aRegistrationDate">aRegistrationDate
	^RegistrationDate 
		ifNotNil: [:eRegistrationDate | self withKey1Decrypt: eRegistrationDate]</body>

<body package="CADSM-UI" selector="aRegistrationDate:">aRegistrationDate: aObject 
	RegistrationDate := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="aRSAPrivateKey1">aRSAPrivateKey1
	^Keys1 at: 2</body>

<body package="CADSM-UI" selector="aRSAPrivateKey2">aRSAPrivateKey2
	^self withKey1Decrypt: (Keys2 at: 2)</body>

<body package="CADSM-UI" selector="aRSAPrivateKey3">aRSAPrivateKey3
	| filepath bos |
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'privatekey.bos'.
	bos := BinaryObjectStorage onOldNoScan: filepath asFilename readStream.
	^[bos contents at: 1] ensure: [bos close]</body>

<body package="CADSM-UI" selector="aRSAPublicKey1">aRSAPublicKey1
	| aPublicKey |
	aPublicKey := Keys1 at: 1.
	^(aPublicKey isMemberOf: Security.RSAPublicKey) 
		ifTrue: [aPublicKey]
		ifFalse: [self withKey1Decrypt: (Keys1 at: 1)]</body>

<body package="CADSM-UI" selector="aRSAPublicKey2">aRSAPublicKey2
	^self withKey1Decrypt: (Keys2 at: 1)</body>

<body package="CADSM-UI" selector="aRSAPublicKey3">aRSAPublicKey3
	| filepath bos |
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'publickey.bos'.
	bos := BinaryObjectStorage onOldNoScan: filepath asFilename readStream.
	^[bos contents at: 1] ensure: [bos close]</body>

<body package="CADSM-UI" selector="aStringID">aStringID
	^'CADSM1 was created on 2004/08/24.'</body>

<body package="CADSM-UI" selector="aSupportExpirationDate">aSupportExpirationDate
	^SupportExpirationDate 
		ifNotNil: [:eSupportExpirationDate | self withKey1Decrypt: eSupportExpirationDate]</body>

<body package="CADSM-UI" selector="aSupportExpirationDate:">aSupportExpirationDate: aObject 
	SupportExpirationDate := self withKey1Encrypt: aObject.
	SaveRequired := true</body>

<body package="CADSM-UI" selector="withKey1Decrypt:">withKey1Decrypt: aByteArray 
	^self withKey: self aRSAPrivateKey1 Decrypt: aByteArray</body>

<body package="CADSM-UI" selector="withKey1Encrypt:">withKey1Encrypt: aObject 
	^self withKey: self aRSAPublicKey1 Encrypt: aObject</body>

<body package="CADSM-UI" selector="withKey2Decrypt:">withKey2Decrypt: aByteArray 
	^self withKey: self aRSAPrivateKey2 Decrypt: aByteArray</body>

<body package="CADSM-UI" selector="withKey3Decrypt:">withKey3Decrypt: aByteArray 
	^self withKey: self aRSAPrivateKey3 Decrypt: aByteArray</body>

<body package="CADSM-UI" selector="withKey3Encrypt:">withKey3Encrypt: aObject 
	^self withKey: self aRSAPublicKey3 Encrypt: aObject</body>

<body package="CADSM-UI" selector="withKey:Decrypt:">withKey: aRSAPrivateKey Decrypt: aByteArray 
	| string |
	string := ((Security.RSA new)
				privateKey: aRSAPrivateKey;
				decryptLong: aByteArray) asByteString.
	^Compiler evaluate: string</body>

<body package="CADSM-UI" selector="withKey:Encrypt:">withKey: aRSAPublicKey Encrypt: aObject 
	| wStream string paddedString |
	wStream := (String new: 1000) writeStream.
	aObject storeOn: wStream.
	string := wStream contents.
	paddedString := (string 
				breakIntoSizeOf: aRSAPublicKey maxByteLengthOfMessage
				padWith: Character space) concatenateCollections.
	^(Security.RSA new)
		publicKey: aRSAPublicKey;
		encryptLong: paddedString asByteArray</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog class</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="abort">abort
	self isRuntime 
		ifTrue: [RuntimePackager.RuntimeManager quitImageNormal]
		ifFalse: [self error: #'Install or Registration error.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="abortInstall">abortInstall
	Dialog warn: (#'The install will be aborted.' &lt;&lt; #'CADSM.UI') expandMacros.
	self abort</body>

<body package="CADSM-UI" selector="bossOutInstallInfo">bossOutInstallInfo
	| aDataRegistration block filepath bos |
	aDataRegistration := CADSMDataRegistration new.
	block := 
			[:symbol | 
			| data edata method |
			data := self perform: symbol.
			edata := self withKey3Encrypt: data.
			method := (symbol , ':') asSymbol.
			aDataRegistration perform: method with: edata].
	block value: #aProductID.
	block value: #aInstallDate.
	block value: #aFullName.
	block value: #aEmail.
	block value: #aRSAPublicKey2.
	block value: #aRSAPrivateKey2.
	filepath := (Filename fromComponents: #('resource')) 
				construct: 'install.bos'.
	bos := BinaryObjectStorage onNew: filepath asFilename writeStream.
	[bos nextPut: aDataRegistration] ensure: [bos close]</body>

<body package="CADSM-UI" selector="clear">clear
	"self clear"

	Email := nil.
	FullName := nil.
	HardwareID := nil.
	InstallDate := nil.
	JustSnapped := nil.
	Keys1 := nil.
	Keys2 := nil.
	LastUsed := nil.
	PatchID := nil.
	ProductID := nil.
	QuitRequired := nil.
	RegistrationDate := nil.
	RegistrationOK := nil.
	SaveRequired := nil.
	SupportExpirationDate := nil</body>

<body package="CADSM-UI" selector="doInstall">doInstall
	"The application is run for the first time."

	Dialog 
		warn: (#'CADSM is doing the initial setup. &lt;n&gt;It can take a few minutes on slow machines.' 
				&lt;&lt; #'CADSM.UI') expandMacros.
	self generateKeys.
	self getAndStoreInstallDate.
	self getAndStoreUserInfo.
	self bossOutInstallInfo</body>

<body package="CADSM-UI" selector="generateKeys">generateKeys
	| nByte nBit aKeyGenClass block |
	nByte := 64.
	nBit := nByte * 8.
	aKeyGenClass := Security.RSAKeyGenerator.
	block := 
			[| aKeyGen |
			aKeyGen := aKeyGenClass keySize: nBit.
			Array with: aKeyGen publicKey with: aKeyGen privateKey].
	Keys1 := block value.
	Keys2 := block value.
	Keys1 at: 1 put: (self withKey1Encrypt: (Keys1 at: 1)).
	Keys2 := Keys2 collect: [:aKey | self withKey1Encrypt: aKey].
	SaveRequired := true</body>

<body package="CADSM-UI" selector="getAndStoreInstallDate">getAndStoreInstallDate
	| now |
	self aProductID: self aStringID.
	now := Timestamp now.
	self aInstallDate: now.
	self aLastUsed: now</body>

<body package="CADSM-UI" selector="getAndStoreUserInfo">getAndStoreUserInfo
	| array dialogResponse |
	array := Array new: 2.
	dialogResponse := self openOn: array
				text: #'Until you decide to register, the information you provide will stay on your computer. To continue using CADSM after the 30-day evaluation period, you must register. Only then do you need to send the information to cadsm.com. Invalid information would require you to reinstall when you register.' 
						&lt;&lt; #'CADSM.UI'.
	dialogResponse ifFalse: [self abortInstall].
	self checkInfoArray: array.
	self aFullName: (array at: 1).
	self aEmail: (array at: 2)</body>

<body package="CADSM-UI" selector="saveImage">saveImage
	self isRuntime 
		ifTrue: 
			[ObjectMemory globalGarbageCollect.
			JustSnapped := ObjectMemory 
						snapshotAs: ObjectMemory imageFilePrefixWithoutPath
						thenQuit: false]
		ifFalse: 
			["For debugging only."

			JustSnapped := true]</body>

<body package="CADSM-UI" selector="startUp">startUp
	"Do nothing."

	</body>

<body package="CADSM-UI" selector="startUp1">startUp1
	"self clear; startUp."

	"self startUp."

	JustSnapped := false.
	SaveRequired := false.
	QuitRequired := false.
	[JustSnapped] whileFalse: 
			[(InstallDate isNil or: [FullName isNil or: [Email isNil]]) 
				ifTrue: [self doInstall]
				ifFalse: [self checkForRegistration].
			SaveRequired 
				ifTrue: 
					[self saveImage.	"Image will relaunch from right after here."
					SaveRequired := false]
				ifFalse: [JustSnapped := true].
			JustSnapped ifTrue: [QuitRequired ifTrue: [self abort]]]</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog class</class-id> <category>testing</category>

<body package="CADSM-UI" selector="checkEmailIn:">checkEmailIn: aDataRegistration 
	self aEmail = (self withKey2Decrypt: aDataRegistration aEmail) 
		ifFalse: [self error: #'Email does not match.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="checkEvaluationPeriod">checkEvaluationPeriod
	| now |
	now := Timestamp now.
	(self aLastUsed &lt; now and: [now &lt; (self aInstallDate addDays: 7)]) 
		ifTrue: [QuitRequired := false]
		ifFalse: 
			[Dialog 
				warn: (#'To use CADSM after the 7-day evaluation period, &lt;n&gt;please register with cadsm.com. It is easy and inexpensive.' 
						&lt;&lt; #'CADSM.UI') expandMacros.
			QuitRequired := true].
	self aLastUsed: now</body>

<body package="CADSM-UI" selector="checkForRegistration">checkForRegistration
	RegistrationOK := nil.
	self isRegistrationOK 
		ifTrue: [QuitRequired := false]
		ifFalse: 
			[self aRegistrationDate ifNotNil: 
					[Dialog 
						warn: (#'There is a problem with the registration of this software. &lt;n&gt;Please contact cadsm.com to resolve the problem.' 
								&lt;&lt; #'CADSM.UI') expandMacros].
			self checkEvaluationPeriod]</body>

<body package="CADSM-UI" selector="checkFullNameIn:">checkFullNameIn: aDataRegistration 
	self aFullName = (self withKey2Decrypt: aDataRegistration aFullName) 
		ifFalse: [self error: #'FullName does not match.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="checkInfoArray:">checkInfoArray: array 
	array do: 
			[:each | 
			each ifNil: 
					[Dialog 
						warn: (#'The required user information is incomplete. &lt;n&gt;The install will be aborted.' 
								&lt;&lt; #'CADSM.UI') expandMacros.
					self abort]]</body>

<body package="CADSM-UI" selector="checkInstallDateIn:">checkInstallDateIn: aDataRegistration 
	self aInstallDate = (self withKey2Decrypt: aDataRegistration aInstallDate) 
		ifFalse: [self error: #'InstallDate does not match.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="checkProductIDIn:">checkProductIDIn: aDataRegistration 
	self aProductID = (self withKey2Decrypt: aDataRegistration aProductID) 
		ifFalse: [self error: #'ProductID does not match.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="checkRegistrationDateIn:">checkRegistrationDateIn: aDataRegistration 
	| a b |
	a := self aRegistrationDate.
	b := self withKey2Decrypt: aDataRegistration aRegistrationDate.
	a ifNil: [self aRegistrationDate: b]
		ifNotNil: 
			[a = b 
				ifFalse: [self error: #'RegistrationDate does not match.' &lt;&lt; #'CADSM.UI']]</body>

<body package="CADSM-UI" selector="checkRSAPrivateKey2In:">checkRSAPrivateKey2In: aDataRegistration 
	self aRSAPrivateKey2 = (self withKey2Decrypt: aDataRegistration aRSAPrivateKey2) 
		ifFalse: [self error: #'RSAPrivateKey2 does not match.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="checkRSAPublicKey2In:">checkRSAPublicKey2In: aDataRegistration 
	self aRSAPublicKey2 = (self withKey2Decrypt: aDataRegistration aRSAPublicKey2) 
		ifFalse: [self error: #'RSAPublicKey2 does not match.' &lt;&lt; #'CADSM.UI']</body>

<body package="CADSM-UI" selector="checkSupportExpirationDateIn:">checkSupportExpirationDateIn: aDataRegistration 
	| oldDate newDate |
	oldDate := self aSupportExpirationDate.
	newDate := self withKey2Decrypt: aDataRegistration aSupportExpirationDate.
	(oldDate isNil or: [oldDate &lt; newDate]) 
		ifTrue: [self aSupportExpirationDate: newDate]
		ifFalse: 
			[oldDate = newDate 
				ifFalse: [self error: #'SupportExpirationDate does not match.' &lt;&lt; #'CADSM.UI']]</body>

<body package="CADSM-UI" selector="isRegistrationOK">isRegistrationOK
	^RegistrationOK ifNil: 
			[RegistrationOK := 
					[| filepath bos cData |
					filepath := (Filename fromComponents: #('resource')) 
								construct: 'register.bos'.
					bos := BinaryObjectStorage onOldNoScan: filepath asFilename readStream.
					[cData := bos contents at: 1] ensure: [bos close].
					self checkProductIDIn: cData.
					self checkInstallDateIn: cData.
					self checkFullNameIn: cData.
					self checkEmailIn: cData.
					self checkRSAPublicKey2In: cData.
					self checkRSAPrivateKey2In: cData.
					self checkRegistrationDateIn: cData.
					self checkSupportExpirationDateIn: cData.
					true] 
							on: Error
							do: [:ex | ex return: false]]</body>

<body package="CADSM-UI" selector="isRuntime">isRuntime
	^#{RuntimePackager.RuntimeManager} ifDefinedDo: 
			[:rtmgr | 
			"We can't test isRuntime, because the runState may still be #aboutToSave when re-entering the image"

			rtmgr runState ~~ #development]
		elseDo: [false]</body>
</methods>

<methods>
<class-id>CADSM.UI.HandleTracker</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aHandle">aHandle
	^aHandle</body>

<body package="CADSM-UI" selector="aHandle:">aHandle: anObject
	aHandle := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.HandleTracker class</class-id> <category>instance-creation</category>

<body package="CADSM-UI" selector="on:">on: aHandle 
	| st |
	st := self new.
	st setController: aHandle aView controller.
	st aHandle: aHandle.
	^st</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser</class-id> <category>scanning</category>

<body package="CADSM-UI" selector="nextString">nextString
	| newStream tab cr element |
	newStream := (source contentsSpecies new: 64) writeStream.
	hereChar isSeparator
		ifTrue: [source skipSeparators]
		ifFalse: [newStream nextPut: hereChar].
	tab := Character tab.
	cr := Character cr.
	[source atEnd]
		whileFalse: 
			[element := source next.
			element = tab
				ifTrue: 
					[hereChar := element.
					^newStream contents]
				ifFalse: [element = cr
						ifTrue: 
							[hereChar := element.
							^newStream contents]].
			newStream nextPut: element].
	^newStream contents</body>

<body package="CADSM-UI" selector="scan:">scan: inputStream 
	"Bind the input stream, fill the character buffers and first token 
	buffer"

	inputStream skipThrough: Character cr.
	super scan: inputStream</body>

<body package="CADSM-UI" selector="xDigit">xDigit
	"form a number"

	tokenType := #number.
	hereChar == nil ifFalse: [source skip: -1].
	token := Number importFrom: source.
	hereChar := source next</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser</class-id> <category>public access</category>

<body package="CADSM-UI" selector="parse:as:">parse: string as: construct 
	self initScanner;
		init: string
		notifying: nil
		failBlock: nil; perform: construct.
	^stack</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser</class-id> <category>geometry</category>

<body package="CADSM-UI" selector="asmt">asmt =
	null Assembly</body>

<body package="CADSM-UI" selector="geoIJSeries">geoIJSeries =
		[
		| fullname |
		fullname := '/' , self nextString.
		self scanToken.
		fullname asSymbol]
	word=#FXonI  signedNumber *
	word=#FYonI  signedNumber *
	word=#FZonI  signedNumber *
	word=#TXonI  signedNumber *
	word=#TYonI  signedNumber *
	word=#TZonI  signedNumber * [
		| TZs TYs TXs FZs FYs FXs fullname assembly geoIJ block ntime nsize dataSeries |
		TZs := stack removeLast.
		TYs := stack removeLast.
		TXs := stack removeLast.
		FZs := stack removeLast.
		FYs := stack removeLast.
		FXs := stack removeLast.
		fullname := stack removeLast.
		assembly := stack removeLast.
		ntime := assembly timeSeries size.
		nsize := ntime + 1.
		block := [:array | array size = nsize ifFalse: [self notify: 'The time series above do not have consistent sizes.' at: mark]].
		block value: TZs.
		block value: TYs.
		block value: TXs.
		block value: FZs.
		block value: FYs.
		block value: FXs.
		geoIJ := nil.
		geoIJ isNil ifTrue: [geoIJ := assembly jointList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly motionList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly generalConstraintSetList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly forceTorqueList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		block := [:i | 
			| answer |
			answer := StCAD.StGeo.GEOForceTorqueData new.
			answer aFIO: (StMFullColumn with: (FXs at: i) with: (FYs at: i) with: (FZs at: i)).
			answer aTIO: (StMFullColumn with: (TXs at: i) with: (TYs at: i) with: (TZs at: i)).
			answer].
		geoIJ inputData: (block value: 1).
		ntime := assembly timeSeries size.
		dataSeries := OrderedCollection new: ntime.
		1 to: ntime do: [:i | dataSeries add: (block value: i + 1)].
		geoIJ dataSeries: dataSeries.
		assembly]</body>

<body package="CADSM-UI" selector="geoIJSeries1">geoIJSeries1 =
	(#/ word) * [
		| fullname |
		fullname := ''.
		stack removeLast do: [:name | fullname := fullname , '/' , name].
		fullname asSymbol]
	word=#FXonI  signedNumber *
	word=#FYonI  signedNumber *
	word=#FZonI  signedNumber *
	word=#TXonI  signedNumber *
	word=#TYonI  signedNumber *
	word=#TZonI  signedNumber * [
		| TZs TYs TXs FZs FYs FXs fullname assembly geoIJ block ntime nsize dataSeries |
		TZs := stack removeLast.
		TYs := stack removeLast.
		TXs := stack removeLast.
		FZs := stack removeLast.
		FYs := stack removeLast.
		FXs := stack removeLast.
		fullname := stack removeLast.
		assembly := stack removeLast.
		ntime := assembly timeSeries size.
		nsize := ntime + 1.
		block := [:array | array size = nsize ifFalse: [self notify: 'The time series above do not have consistent sizes.' at: mark]].
		block value: TZs.
		block value: TYs.
		block value: TXs.
		block value: FZs.
		block value: FYs.
		block value: FXs.
		geoIJ := nil.
		geoIJ isNil ifTrue: [geoIJ := assembly jointList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly motionList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly generalConstraintSetList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly forceTorqueList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		block := [:i | 
			| answer |
			answer := DataForceTorque new.
			answer aFIO: (StMFullColumn with: (FXs at: i) with: (FYs at: i) with: (FZs at: i)).
			answer aTIO: (StMFullColumn with: (TXs at: i) with: (TYs at: i) with: (TZs at: i)).
			answer].
		geoIJ inputData: (block value: 1).
		ntime := assembly timeSeries size.
		dataSeries := OrderedCollection new: ntime.
		1 to: ntime do: [:i | dataSeries add: (block value: i + 1)].
		geoIJ dataSeries: dataSeries.
		assembly]</body>

<body package="CADSM-UI" selector="null">null =</body>

<body package="CADSM-UI" selector="tension">tension
	^(tokenType == #word and: [token = 'tension'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque tensionFunc: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="twist">twist
	^(tokenType == #word and: [token = 'twist'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque twistFunc: function.
			self scanToken.
			true]
		ifFalse: [false]</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser</class-id> <category>geometry2</category>

<body package="CADSM-UI" selector="angIJJ1">angIJJ1
	^(tokenType == #word and: [token = 'angIJJ1']) 
		ifTrue: 
			[| aGeneralMotion function |
			aGeneralMotion := stack last.
			function := StCAD.StMath.BasicUserFunction 
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			aGeneralMotion phiIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="angIJJ2">angIJJ2
	^(tokenType == #word and: [token = 'angIJJ2']) 
		ifTrue: 
			[| aGeneralMotion function |
			aGeneralMotion := stack last.
			function := StCAD.StMath.BasicUserFunction 
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			aGeneralMotion theIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="angIJJ3">angIJJ3
	^(tokenType == #word and: [token = 'angIJJ3']) 
		ifTrue: 
			[| aGeneralMotion function |
			aGeneralMotion := stack last.
			function := StCAD.StMath.BasicUserFunction 
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			aGeneralMotion psiIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="Angle">Angle =
	word=#Angle signedNumber [
			| angle refFrame cos sin msin aAFf |
			angle := stack removeLast.
			refFrame := stack removeLast.
			cos := angle cos.
			sin := angle sin.
			msin := sin negated.
			aAFf := refFrame aAFf.
			(aAFf at: 1) at: 1 put: cos; at: 2 put: msin; at: 3 put: 0.0d.
			(aAFf at: 2) at: 1 put: sin; at: 2 put: cos; at: 3 put: 0.0d.
			(aAFf at: 3) at: 1 put: 0.0d; at: 2 put: 0.0d; at: 3 put: 1.0d.
			refFrame]</body>

<body package="CADSM-UI" selector="AnimationParameters">AnimationParameters =
	word=#AnimationParameters [
		StCAD.StGeo.GEOAnimationData new]
	word=#nframe number 
	word=#icurrent number 
	word=#istart number 
	word=#iend number 
	word=#isForward word 
	word=#framesPerSecond number [
		| framesPerSecond isForward iend istart icurrent nframe aniData assembly |
		framesPerSecond := stack removeLast.
		isForward := stack removeLast asLowercase = 'true'.
		iend := stack removeLast.
		istart := stack removeLast.
		icurrent := stack removeLast.
		nframe := stack removeLast.
		aniData := stack removeLast.
		assembly := stack removeLast.
		aniData nframe: nframe; icurrent: icurrent; istart: istart; iend: iend; isForward: isForward; framesPerSecond: framesPerSecond.
		assembly animationData: aniData.
		assembly]</body>

<body package="CADSM-UI" selector="Assembly">Assembly =
	word=#Assembly [
		CADSM.Geo.Assembly new]
	Notes
	Name
	RefFrame
	RefPoints
	RefCurves
	RefSurfaces
	Parts
	KinematicIJs
	ConstraintSets
	ForceTorques
	ConstantGravity
	SimulationParameters
	AnimationParameters
	(TimeSeries | ) [
		| assembly |
		assembly := stack removeLast.
		assembly partList do: [:part | part privateBuildSolidModel].
		assembly jointList do: [:item | item validateFormulas].
		assembly motionList do: [:item | item validateFormulas].
		assembly forceTorqueList do: [:item | item validateFormulas].
		assembly]</body>

<body package="CADSM-UI" selector="Circle">Circle =
	word=#Circle [CADSM.Geo.Circle new]
	RefFrame2D
	word=#Radius number [
		| radius circle |
		radius := stack removeLast.
		circle := stack removeLast.
		circle radius: radius.
		circle calc.
		circle privateCalcBoundingBox.
		circle]</body>

<body package="CADSM-UI" selector="ConstantGravity">ConstantGravity =
	word=#ConstantGravity signedNumber signedNumber signedNumber [
		| gZ gY gX assembly gXYZ |
		gZ := stack removeLast.
		gY := stack removeLast.
		gX := stack removeLast.
		assembly := stack removeLast.
		gXYZ := assembly gravity gXYZ.
		gXYZ at: 1 put: gX.
		gXYZ at: 2 put: gY.
		gXYZ at: 3 put: gZ.
		assembly]</body>

<body package="CADSM-UI" selector="ConstraintSets">ConstraintSets =
	word=#ConstraintSets
	Joints
	Motions
	GeneralConstraintSets</body>

<body package="CADSM-UI" selector="CurveCurveContact">CurveCurveContact =
	word=#CurveCurveContact [
		CADSM.Geo.CVCVJoint new]
	Name
	MarkerI
	MarkerJ
	word=#coeffRestitution signedNumber [
		| coeffRestitution contact |
		coeffRestitution := stack removeLast.
		contact := stack removeLast.
		contact coeffRestitution: coeffRestitution.
		contact]</body>

<body package="CADSM-UI" selector="CurveCurveContactSeries">CurveCurveContactSeries =
	word=#CurveCurveContactSeries [
		| fullname |
		fullname := '/' , self nextString.
		self scanToken.
		fullname asSymbol]
	word=#FXonI  signedNumber *
	word=#FYonI  signedNumber *
	word=#FZonI  signedNumber *
	word=#TXonI  signedNumber *
	word=#TYonI  signedNumber *
	word=#TZonI  signedNumber * 
	word=#sI signedNumber *
	word=#sdotI signedNumber *
	word=#sddotI signedNumber *
	word=#sJ signedNumber *
	word=#sdotJ signedNumber *
	word=#sddotJ signedNumber * [
		| sddotJs sdotJs sJs sddotIs sdotIs sIs TZs TYs TXs FZs FYs FXs fullname assembly geoIJ block ntime nsize dataSeries markerI markerJ |
		sddotJs := stack removeLast.
		sdotJs := stack removeLast.
		sJs := stack removeLast.
		sddotIs := stack removeLast.
		sdotIs := stack removeLast.
		sIs := stack removeLast.
		TZs := stack removeLast.
		TYs := stack removeLast.
		TXs := stack removeLast.
		FZs := stack removeLast.
		FYs := stack removeLast.
		FXs := stack removeLast.
		fullname := stack removeLast.
		assembly := stack removeLast.
		ntime := assembly timeSeries size.
		nsize := ntime + 1.
		block := [:array | array size = nsize ifFalse: [self notify: 'The time series above do not have consistent sizes.' at: mark]].
		block value: sddotJs.
		block value: sdotJs.
		block value: sJs.
		block value: sddotIs.
		block value: sdotIs.
		block value: sIs.
		block value: TZs.
		block value: TYs.
		block value: TXs.
		block value: FZs.
		block value: FYs.
		block value: FXs.
		geoIJ := nil.
		geoIJ isNil ifTrue: [geoIJ := assembly jointList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly motionList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly generalConstraintSetList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		geoIJ isNil ifTrue: [geoIJ := assembly forceTorqueList detect: [:geoItem | geoItem fullName = fullname] ifNone: nil].
		block := [:i | 
			| answer |
			answer := DataForceTorque new.
			answer aFIO: (StMFullColumn with: (FXs at: i) with: (FYs at: i) with: (FZs at: i)).
			answer aTIO: (StMFullColumn with: (TXs at: i) with: (TYs at: i) with: (TZs at: i)).
			answer].
		geoIJ inputData: (block value: 1).
		dataSeries := OrderedCollection new: ntime.
		1 to: ntime do: [:i | dataSeries add: (block value: i + 1)].
		geoIJ dataSeries: dataSeries.
		block := [:i | 
			| answer |
			answer := DataSSdotSddot new.
			answer s: (StMFullColumn with: (sIs at: i)).
			answer sdot: (StMFullColumn with: (sdotIs at: i)).
			answer sddot: (StMFullColumn with: (sddotIs at: i)).
			answer].
		markerI := geoIJ aMarkerI.
		markerI inputData: (block value: 1).
		dataSeries := OrderedCollection new: ntime.
		1 to: ntime do: [:i | dataSeries add: (block value: i + 1)].
		markerI dataSeries: dataSeries.
		block := [:i | 
			| answer |
			answer := DataSSdotSddot new.
			answer s: (StMFullColumn with: (sJs at: i)).
			answer sdot: (StMFullColumn with: (sdotJs at: i)).
			answer sddot: (StMFullColumn with: (sddotJs at: i)).
			answer].
		markerJ := geoIJ aMarkerJ.
		markerJ inputData: (block value: 1).
		dataSeries := OrderedCollection new: ntime.
		1 to: ntime do: [:i | dataSeries add: (block value: i + 1)].
		markerJ dataSeries: dataSeries.
		assembly]</body>

<body package="CADSM-UI" selector="CurveMarker">CurveMarker =
	word=#CurveMarker [
		CADSM.Geo.CurveMarker new]
	Name
	word=#s signedNumber [
		| s marker |
		s := stack removeLast.
		marker := stack removeLast.
		marker s: s.
		marker]</body>

<body package="CADSM-UI" selector="CurveMarkers">CurveMarkers =
	word=#CurveMarkers
	CurveMarker * [
		| markers refItem |
		markers := stack removeLast.
		refItem := stack removeLast.
		refItem addCurveMarkers: markers.
		refItem]</body>

<body package="CADSM-UI" selector="CurvePoints">CurvePoints =
	word=#CurvePoints
	word=#Number number *
	word=#s signedNumber *
	word=#x signedNumber *
	word=#y signedNumber *
	word=#z signedNumber * [
		| zs ys xs ss ns spline n rFpointsF |
		zs := stack removeLast.
		ys := stack removeLast.
		xs := stack removeLast.
		ss := stack removeLast.
		ns := stack removeLast.
		spline := stack removeLast.
		n := ns size.
		(xs size = n and: [ys size = n  and: [zs size = n]])
			ifFalse: [self notify: 'Some data points are not valid.'.].
		rFpointsF := ns class new: n.
		1 to: n do: [:i | rFpointsF at: i put: (StMFullColumn with: (xs at: i) with: (ys at: i) with: (zs at: i))].
		spline xs: ss.
		spline ys: rFpointsF.
		spline]</body>

<body package="CADSM-UI" selector="Cut">Cut =
	word=#Cut [
		ExtrudedFeature new]
	word=#zStart signedNumber [
		| zStart cut |
		zStart := stack removeLast.
		cut := stack removeLast.
		cut zStart: zStart.
		cut]
	word=#zEnd signedNumber [
		| zEnd cut |
		zEnd := stack removeLast.
		cut := stack removeLast.
		cut zEnd: zEnd.
		cut]
	Sketch</body>

<body package="CADSM-UI" selector="DataPoints">DataPoints =
	word=#DataPoints
	word=#Number number *
	word=#s signedNumber *
	word=#x signedNumber *
	word=#y signedNumber *
	word=#z signedNumber * [
		| zs ys xs ss ns spline n rFpointsF |
		zs := stack removeLast.
		ys := stack removeLast.
		xs := stack removeLast.
		ss := stack removeLast.
		ns := stack removeLast.
		spline := stack removeLast.
		n := ns size.
		(xs size = n and: [ys size = n  and: [zs size = n]])
			ifFalse: [self notify: 'Some data points are not valid.'.].
		rFpointsF := ns class new: n.
		1 to: n do: [:i | rFpointsF at: i put: (StMFullColumn with: (xs at: i) with: (ys at: i) with: (zs at: i))].
		spline xs: ss.
		spline ys: rFpointsF.
		spline]</body>

<body package="CADSM-UI" selector="Ellipse">Ellipse =
	word=#Ellipse [CADSM.Geo.Ellipse new]
	RefFrame2D
	word=#xRadius number
	word=#yRadius number [
		| yRadius xRadius ellipse |
		yRadius := stack removeLast.
		xRadius := stack removeLast.
		ellipse := stack removeLast.
		ellipse xRadius: xRadius.
		ellipse yRadius: yRadius.
		ellipse calc.
		ellipse privateCalcBoundingBox.
		ellipse]</body>

<body package="CADSM-UI" selector="Extrusion">Extrusion =
	word=#Extrusion [ExtrudedFeature new]
	word=#zStart signedNumber [
		| zStart extrusion |
		zStart := stack removeLast.
		extrusion := stack removeLast.
		extrusion zStart: zStart.
		extrusion]
	word=#zEnd signedNumber [
		| zEnd extrusion |
		zEnd := stack removeLast.
		extrusion := stack removeLast.
		extrusion zEnd: zEnd.
		extrusion]
	Sketch [
		| aSketch extrusion |
		aSketch := stack removeLast.
		extrusion := stack removeLast.
		extrusion aSketch: aSketch.
		extrusion]</body>

<body package="CADSM-UI" selector="Feature">Feature =
	Extrusion | Cut</body>

<body package="CADSM-UI" selector="FeatureOrder">FeatureOrder =
	word=#FeatureOrder
	Feature * [
		| features anyPart |
		features := stack removeLast.
		anyPart := stack removeLast.
		anyPart addFeatureOrder: features.
		anyPart]</body>

<body package="CADSM-UI" selector="ForceTorque">ForceTorque =
	InLineForceTorque | GeneralForceTorque</body>

<body package="CADSM-UI" selector="ForceTorques">ForceTorques =
	word=#ForceTorques
	ForceTorque * [
		| forceTorques assembly |
		forceTorques := stack removeLast.
		assembly := stack removeLast.
		assembly addForceTorques: forceTorques.
		assembly]</body>

<body package="CADSM-UI" selector="ForceTorqueSeries">ForceTorqueSeries =
	(word=#InlineForceTorqueSeries | word=#GeneralForceTorqueSeries) geoIJSeries</body>

<body package="CADSM-UI" selector="FxOnI">FxOnI
	^(tokenType == #word and: [token = 'FxOnI'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque aFIeKe at: 1 put: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="FyOnI">FyOnI
	^(tokenType == #word and: [token = 'FyOnI'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque aFIeKe at: 2 put: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="FzOnI">FzOnI
	^(tokenType == #word and: [token = 'FzOnI'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque aFIeKe at: 3 put: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="GeneralConstraintSet">GeneralConstraintSet =
	word=#GeneralConstraintSet [
		CADSM.UI.GEOConstraintSet new]</body>

<body package="CADSM-UI" selector="GeneralConstraintSets">GeneralConstraintSets =
	word=#GeneralConstraintSets
	GeneralConstraintSet * [
		| generalConstraintSets assembly |
		generalConstraintSets := stack removeLast.
		assembly := stack removeLast.
		assembly addGeneralConstraintSets: generalConstraintSets.
		assembly]</body>

<body package="CADSM-UI" selector="GeneralConstraintSetSeries">GeneralConstraintSetSeries =
	(word=#GeneralConstraintSetSeries) geoIJSeries</body>

<body package="CADSM-UI" selector="GeneralForceTorque">GeneralForceTorque =
	word=#GeneralForceTorque [
		CADSM.Geo.ForceTorqueGeneral new]
	Name
	MarkerI
	MarkerJ
	FxOnI
	FyOnI
	FzOnI
	TxOnI
	TyOnI
	TzOnI
	MarkerK</body>

<body package="CADSM-UI" selector="GeneralMotion">GeneralMotion =
	word=#GeneralMotion [
		CADSM.UI.GEOGeneralMotion new]
	Name
	MarkerI
	MarkerJ
	rIJI1
	rIJI2
	rIJI3
	angIJJ1
	angIJJ2
	angIJJ3
	RotationOrder</body>

<body package="CADSM-UI" selector="GeneralSpline">GeneralSpline =
	word=#GeneralSpline [
		| spline |
		spline:= StCAD.StMath.StMGeneralSpline new.
		spline x: StMIndependentVariable new.
		spline]
	word=#Order number [
		| order spline |
		order := stack removeLast.
		spline := stack removeLast.
		spline degree: order.
		spline]
	DataPoints [
		| spline refCurve |
		spline := stack removeLast.
		refCurve := stack removeLast.
		refCurve rfCurvef: spline computeDerivatives.
		refCurve]</body>

<body package="CADSM-UI" selector="Graphic">Graphic =
	Rectangle | Circle | Ellipse | Polyline</body>

<body package="CADSM-UI" selector="Graphics">Graphics =
	word=#Graphics
	Graphic * [
		| graphics sketch |
		graphics := stack removeLast.
		sketch := stack removeLast.
		sketch addGraphics: graphics.
		sketch]</body>

<body package="CADSM-UI" selector="InLineForceTorque">InLineForceTorque =
	word=#InLineForceTorque [
		CADSM.Geo.ForceTorqueInLine new]
	Name
	MarkerI
	MarkerJ
	tension
	twist</body>

<body package="CADSM-UI" selector="Joint">Joint =
	CurveCurveContact | RackPinionJoint | ScrewJoint | OtherJoint</body>

<body package="CADSM-UI" selector="Joints">Joints =
	word=#Joints
	Joint * [
		| joints assembly |
		joints := stack removeLast.
		assembly := stack removeLast.
		assembly addJoints: joints.
		assembly]</body>

<body package="CADSM-UI" selector="JointSeries">JointSeries =
	((word=#ConstantVelocityJointSeries
	| word=#CylindricalJointSeries
	| word=#FixedJointSeries
	| word=#InLineJointSeries
	| word=#InPlaneJointSeries
	| word=#NoRotationJointSeries
	| word=#ParallelAxesJointSeries
	| word=#PerpendicularJointSeries
	| word=#PlanarJointSeries
	| word=#RackPinionJointSeries
	| word=#RevoluteJointSeries
	| word=#ScrewJointSeries
	| word=#SphericalJointSeries
	| word=#TranslationalJointSeries
	| word=#UniversalJointSeries) geoIJSeries) | CurveCurveContactSeries</body>

<body package="CADSM-UI" selector="KinematicIJ">KinematicIJ =
	word=#KinematicIJ [
		CADSM.UI.GEOKineIJ new]
	Name
	MarkerI
	MarkerJ</body>

<body package="CADSM-UI" selector="KinematicIJs">KinematicIJs =
	word=#KinematicIJs
	KinematicIJ * [
		| kinematicIJs assembly |
		kinematicIJs := stack removeLast.
		assembly := stack removeLast.
		assembly addKinematicIJs: kinematicIJs.
		assembly]</body>

<body package="CADSM-UI" selector="Marker">Marker =
	word=#Marker [Marker new]
	Name
	RefFrame</body>

<body package="CADSM-UI" selector="MarkerI">MarkerI
	^(tokenType == #word and: [token = 'MarkerI'])
		ifTrue: 
			[| components assembly markerI geoIJ |
			components := self nextString tokensBasedOn: $/.
			components removeFirst.
			components := components collect: [:component | component asSymbol].
			geoIJ := stack last.
			assembly := stack first.
			markerI := (assembly findMarkerNamed: components) ifNil: [assembly findMarkerNamedOld: components].
			markerI ifNil: [self notify: 'MarkerI has not been defined.' at: mark].
			geoIJ aMarkerI: markerI.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="MarkerI1">MarkerI1 =
	word=#MarkerI
	(#/ word) * [
		| nameComponents geoIJ assembly markerI |
		nameComponents := stack removeLast collect: [:component | component asSymbol].
		geoIJ := stack removeLast.
		assembly := stack first.
		markerI := assembly findMarkerNamed: nameComponents.
		markerI isNil ifTrue: [self notify: 'MarkerI has not been defined.' at: mark].
		geoIJ aMarkerI: markerI.
		geoIJ]</body>

<body package="CADSM-UI" selector="MarkerJ">MarkerJ
	^(tokenType == #word and: [token = 'MarkerJ'])
		ifTrue: 
			[| components assembly markerJ geoIJ |
			components := self nextString tokensBasedOn: $/.
			components removeFirst.
			components := components collect: [:component | component asSymbol].
			geoIJ := stack last.
			assembly := stack first.
			markerJ := (assembly findMarkerNamed: components) ifNil: [assembly findMarkerNamedOld: components].
			markerJ isNil ifTrue: [self notify: 'MarkerJ has not been defined.' at: mark].
			geoIJ aMarkerJ: markerJ.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="MarkerK">MarkerK =
	word=#MarkerK
	(word=#I [#I] | word=#J [#J] | word=#O [#O]) [
		| markerK forceTorque |
		markerK := stack removeLast.
		forceTorque := stack removeLast.
		forceTorque markerK: markerK.
		forceTorque]</body>

<body package="CADSM-UI" selector="Markers">Markers =
	word=#Markers
	Marker * [
		| markers refItem |
		markers := stack removeLast.
		refItem := stack removeLast.
		refItem addMarkers: markers.
		refItem]</body>

<body package="CADSM-UI" selector="Motion">Motion =
	GeneralMotion | RotationMotion | TranslationMotion</body>

<body package="CADSM-UI" selector="MotionJoint">MotionJoint =
	word=#MotionJoint
	(#/ word) * [
		| nameComponents geoIJ assembly joint |
		nameComponents := stack removeLast collect: [:component | component asSymbol].
		geoIJ := stack removeLast.
		assembly := stack first.
		joint := assembly jointList detect: [:jt | jt name = nameComponents last].
		joint isNil ifTrue: [self notify: 'MotionJoint has not been defined.' at: mark].
		geoIJ aMarkerI: joint aMarkerI.
		geoIJ aMarkerJ: joint aMarkerJ.
		geoIJ]</body>

<body package="CADSM-UI" selector="Motions">Motions =
	word=#Motions
	Motion * [
		| motions assembly |
		motions := stack removeLast.
		assembly := stack removeLast.
		assembly addMotions: motions.
		assembly]</body>

<body package="CADSM-UI" selector="MotionSeries">MotionSeries =
	(word=#RotationalMotionSeries | word=#TranslationalMotionSeries | word=#GeneralMotionSeries) geoIJSeries</body>

<body package="CADSM-UI" selector="rIJI1">rIJI1
	^(tokenType == #word and: [token = 'rIJI1']) 
		ifTrue: 
			[| aGeneralMotion function |
			aGeneralMotion := stack last.
			function := StCAD.StMath.BasicUserFunction 
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			aGeneralMotion xIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="rIJI2">rIJI2
	^(tokenType == #word and: [token = 'rIJI2']) 
		ifTrue: 
			[| aGeneralMotion function |
			aGeneralMotion := stack last.
			function := StCAD.StMath.BasicUserFunction 
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			aGeneralMotion yIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="rIJI3">rIJI3
	^(tokenType == #word and: [token = 'rIJI3']) 
		ifTrue: 
			[| aGeneralMotion function |
			aGeneralMotion := stack last.
			function := StCAD.StMath.BasicUserFunction 
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			aGeneralMotion zIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="RotationOrder">RotationOrder =
	word=#RotationOrder number number number [
		| axis3 axis2 axis1 aGeneralMotion |
		axis3 := stack removeLast.
		axis2 := stack removeLast.
		axis1 := stack removeLast.
		aGeneralMotion := stack removeLast.
		aGeneralMotion rotOrder: (Array with: axis1 with: axis2 with: axis3).
		aGeneralMotion]</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser</class-id> <category>geometry3</category>

<body package="CADSM-UI" selector="Name">Name
	^(tokenType == #word and: [token = 'Name'])
		ifTrue: 
			[| geoItem name |
			geoItem := stack last.
			name := self nextString.
			geoItem name: name.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="Name1">Name1 =
	word=#Name word [
		| assembly name |
		name := stack removeLast.
		assembly := stack removeLast.
		assembly name: name.
		assembly]</body>

<body package="CADSM-UI" selector="Notes">Notes
	^(tokenType == #word and: [token = 'Notes'])
		ifTrue: 
			[| assembly notes |
			assembly := stack last.
			notes := self nextString expandMacros copyWithout: $".
			assembly notes: (Text readFrom: notes).
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="Omega3D">Omega3D =
	word=#Omega3D signedNumber signedNumber signedNumber [
		| omeOfO3 omeOfO2 omeOfO1 refFrame omeOfO |
		omeOfO3 := stack removeLast.
		omeOfO2 := stack removeLast.
		omeOfO1 := stack removeLast.
		refFrame := stack removeLast.
		omeOfO := StMFullColumn new: 3.
		omeOfO at: 1 put: omeOfO1.
		omeOfO at: 2 put: omeOfO2.
		omeOfO at: 3 put: omeOfO3.
		refFrame omeOfO: omeOfO.
		refFrame]</body>

<body package="CADSM-UI" selector="OtherJoint">OtherJoint
	| geoClass |
	(tokenType == #word and: [(geoClass := NameToGEOdict at: token asSymbol) notNil])
		ifTrue: 
			[self scanToken.
			stack addLast: geoClass new.
			self Name
				ifTrue: 
					[self MarkerI
						ifTrue: 
							[self MarkerJ ifTrue: [^true].
							^self expected: 'MarkerJ'].
					^self expected: 'MarkerI'].
			^self expected: 'Name'].
	^false</body>

<body package="CADSM-UI" selector="Part">Part =
	word=#Part [CADSM.Geo.Part new]
	Name
	RefFrame
	FeatureOrder
	PrincipalMassMarker
	RefPoints
	RefCurves
	RefSurfaces</body>

<body package="CADSM-UI" selector="Parts">Parts =
	word=#Parts
	Part * [
		| parts assembly |
		parts := stack removeLast.
		assembly := stack removeLast.
		assembly addAnyParts: parts.
		assembly]</body>

<body package="CADSM-UI" selector="PartSeries">PartSeries =
	(word=#AssemblySeries | word=#PartSeries) [
		| fullname |
		fullname := '/' , self nextString.
		self scanToken.
		fullname asSymbol]
	word=#X signedNumber *
	word=#Y signedNumber *
	word=#Z signedNumber *
	word=#Bryantx signedNumber *
	word=#Bryanty signedNumber *
	word=#Bryantz signedNumber *
	word=#VX signedNumber *
	word=#VY signedNumber *
	word=#VZ signedNumber *
	word=#OmegaX signedNumber *
	word=#OmegaY signedNumber *
	word=#OmegaZ signedNumber *
	word=#AX signedNumber *
	word=#AY signedNumber *
	word=#AZ signedNumber *
	word=#AlphaX signedNumber *
	word=#AlphaY signedNumber *
	word=#AlphaZ signedNumber * [
		| AlphaZs AlphaYs AlphaXs AZs AYs AXs OmegaZs OmegaYs OmegaXs VZs VYs VXs Bryantzs Bryantys Bryantxs Zs Ys Xs fullname assembly part block ntime nsize dataSeries |
		AlphaZs := stack removeLast.
		AlphaYs := stack removeLast.
		AlphaXs := stack removeLast.
		AZs := stack removeLast.
		AYs := stack removeLast.
		AXs := stack removeLast.
		OmegaZs := stack removeLast.
		OmegaYs := stack removeLast.
		OmegaXs := stack removeLast.
		VZs := stack removeLast.
		VYs := stack removeLast.
		VXs := stack removeLast.
		Bryantzs := stack removeLast.
		Bryantys := stack removeLast.
		Bryantxs := stack removeLast.
		Zs := stack removeLast.
		Ys := stack removeLast.
		Xs := stack removeLast.
		fullname := stack removeLast.
		assembly := stack removeLast.
		ntime := assembly timeSeries size.
		nsize := ntime + 1.
		block := [:array | array size = nsize ifFalse: [self notify: 'The time series above do not have consistent sizes.' at: mark]].
		block value: AlphaZs.
		block value: AlphaYs.
		block value: AlphaXs.
		block value: AZs.
		block value: AYs.
		block value: AXs.
		block value: OmegaZs.
		block value: OmegaYs.
		block value: OmegaXs.
		block value: VZs.
		block value: VYs.
		block value: VXs.
		block value: Bryantzs.
		block value: Bryantys.
		block value: Bryantxs.
		block value: Zs.
		block value: Ys.
		block value: Xs.
		part := assembly fullName = fullname 
				ifTrue: [assembly] 
				ifFalse: [assembly partList detect: [:anyPart | anyPart fullName = fullname]].
		block := [:i | 
			| answer |
			answer := StCAD.StGeo.GEOPosVelAccData new.
			answer rOfO: (StMFullColumn with: (Xs at: i) with: (Ys at: i) with: (Zs at: i)).
			answer aAOf: ((StCAD.StGeo.GEOEulerAnglesxyz with: (Bryantxs at: i) with: (Bryantys at: i) with: (Bryantzs at: i)) calc; aA).
			answer vOfO: (StMFullColumn with: (VXs at: i) with: (VYs at: i) with: (VZs at: i)).
			answer omeOfO: (StMFullColumn with: (OmegaXs at: i) with: (OmegaYs at: i) with: (OmegaZs at: i)).
			answer aOfO: (StMFullColumn with: (AXs at: i) with: (AYs at: i) with: (AZs at: i)).
			answer alpOfO: (StMFullColumn with: (AlphaXs at: i) with: (AlphaYs at: i) with: (AlphaZs at: i)).
			answer].
		part inputData: (block value: 1).
		ntime := assembly timeSeries size.
		dataSeries := OrderedCollection new: ntime.
		1 to: ntime do: [:i | dataSeries add: (block value: i + 1)].
		part dataSeries: dataSeries.
		assembly]</body>

<body package="CADSM-UI" selector="Polyline">Polyline =
	word=#Polyline [
		CADSM.Geo.Polyline new]
	RefFrame2D
	Vertices</body>

<body package="CADSM-UI" selector="Position2D">Position2D =
	word=#Position2D signedNumber signedNumber [
		| y x refFrame rFfF |
		y := stack removeLast.
		x := stack removeLast.
		refFrame := stack removeLast.
		rFfF := refFrame rFfF.
		rFfF at: 1 put: x.
		rFfF at: 2 put: y.
		rFfF at: 3 put: 0.0d.
		refFrame]</body>

<body package="CADSM-UI" selector="Position3D">Position3D =
	word=#Position3D signedNumber signedNumber signedNumber [
		| z y x refFrame rFfF |
		z := stack removeLast.
		y := stack removeLast.
		x := stack removeLast.
		refFrame := stack removeLast.
		rFfF := refFrame rFfF.
		rFfF at: 1 put: x.
		rFfF at: 2 put: y.
		rFfF at: 3 put: z.
		refFrame]</body>

<body package="CADSM-UI" selector="PrincipalMassMarker">PrincipalMassMarker =
	word=#PrincipalMassMarker [MassMarker new]
	Name
	RefFrame
	word=#Mass number [
		| mass massMarker |
		mass := stack removeLast.
		massMarker := stack removeLast.
		massMarker mass: mass.
		massMarker]
	word=#MomentOfInertias number number number [
		| aJppz aJppy aJppx massMarker |
		aJppz := stack removeLast.
		aJppy := stack removeLast.
		aJppx := stack removeLast.
		massMarker := stack removeLast.
		massMarker aJppx: aJppx.
		massMarker aJppy: aJppy.
		massMarker aJppz: aJppz.
		massMarker]
	word=#Density number [
		| density massMarker |
		density := stack removeLast.
		massMarker := stack removeLast.
		massMarker density: density.
		massMarker]
	[
		| massMarker part |
		massMarker := stack removeLast.
		part := stack removeLast.
		part aMassMarker: massMarker.
		part]</body>

<body package="CADSM-UI" selector="RackPinionJoint">RackPinionJoint =
	word=#RackPinionJoint [
		CADSM.UI.GEORackPinJoint new]
	Name
	MarkerI
	MarkerJ
	word=#pitchRadius signedNumber [
		| pitchRadius joint |
		pitchRadius := stack removeLast.
		joint := stack removeLast.
		joint pitchRadius: pitchRadius.
		joint]</body>

<body package="CADSM-UI" selector="Rectangle">Rectangle =
	word=#Rectangle [CADSM.Geo.Rectangle new]
	RefFrame2D
	word=#xLength number 
	word=#yLength number [
		| yLength xLength rectangle |
		yLength := stack removeLast.
		xLength := stack removeLast.
		rectangle := stack removeLast.
		rectangle xLength: xLength; yLength: yLength.
		rectangle calc.
		rectangle privateCalcBoundingBox.
		rectangle]</body>

<body package="CADSM-UI" selector="RefCurve">RefCurve =
	word=#RefCurve [
		CADSM.Geo.RefCurve new]
	RefFrame
	GeneralSpline
	CurveMarkers</body>

<body package="CADSM-UI" selector="RefCurves">RefCurves =
	word=#RefCurves
	RefCurve * [
		| refCurves anyPart |
		refCurves := stack removeLast.
		anyPart := stack removeLast.
		anyPart addRefCurves: refCurves.
		anyPart]</body>

<body package="CADSM-UI" selector="RefFrame">RefFrame =
	[stack last aRefFrame]
	null
	Position3D
	RotationMatrix
	(Velocity3D Omega3D | )
	[stack removeLast].</body>

<body package="CADSM-UI" selector="RefFrame2D">RefFrame2D =
	[stack last aRefFrame]
	null
	Position2D
	Angle
	[stack removeLast].</body>

<body package="CADSM-UI" selector="RefPoint">RefPoint =
	word=#RefPoint [CADSM.Geo.RefPoint new]
	RefFrame
	Markers</body>

<body package="CADSM-UI" selector="RefPoints">RefPoints =
	word=#RefPoints
	RefPoint * [
		| refPoints anyPart |
		refPoints := stack removeLast.
		anyPart := stack removeLast.
		anyPart addRefPoints: refPoints.
		anyPart]</body>

<body package="CADSM-UI" selector="RefSurface">RefSurface =
	word=#RefSurface [
		CADSM.Geo.RefSurface new]
	RefFrame
	SurfaceMarkers</body>

<body package="CADSM-UI" selector="RefSurfaces">RefSurfaces =
	word=#RefSurfaces
	RefSurface * [
		| refSurfaces anyPart |
		refSurfaces := stack removeLast.
		anyPart := stack removeLast.
		anyPart addRefSurfaces: refSurfaces.
		anyPart]</body>

<body package="CADSM-UI" selector="RotationMatrix">RotationMatrix =
	word=#RotationMatrix 
		signedNumber signedNumber signedNumber 
		signedNumber signedNumber signedNumber 
		signedNumber signedNumber signedNumber [
			| a11 a12 a13 a21 a22 a23 a31 a32 a33 refFrame aAFf |
			a33 := stack removeLast.
			a32 := stack removeLast.
			a31 := stack removeLast.
			a23 := stack removeLast.
			a22 := stack removeLast.
			a21 := stack removeLast.
			a13 := stack removeLast.
			a12 := stack removeLast.
			a11 := stack removeLast.
			refFrame := stack removeLast.
			aAFf := refFrame aAFf.
			(aAFf at: 1) at: 1 put: a11; at: 2 put: a12; at: 3 put: a13.
			(aAFf at: 2) at: 1 put: a21; at: 2 put: a22; at: 3 put: a23.
			(aAFf at: 3) at: 1 put: a31; at: 2 put: a32; at: 3 put: a33.
			refFrame]</body>

<body package="CADSM-UI" selector="RotationMotion">RotationMotion =
	word=#RotationalMotion [RotationalMotion new]
	Name
	MotionJoint
	RotationZ</body>

<body package="CADSM-UI" selector="RotationZ">RotationZ
	^(tokenType == #word and: [token = 'RotationZ'])
		ifTrue: 
			[| motion function |
			motion := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			motion phiIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="ScrewJoint">ScrewJoint =
	word=#ScrewJoint [
		CADSM.UI.GEOScrewJoint new]
	Name
	MarkerI
	MarkerJ
	word=#pitch signedNumber [
		| pitch joint |
		pitch := stack removeLast.
		joint := stack removeLast.
		joint pitch: pitch.
		joint]</body>

<body package="CADSM-UI" selector="SimulationParameters">SimulationParameters =
	word=#SimulationParameters [StCAD.StGeo.GEOSimulationData new]
	word=#tstart number 
	word=#tend number 
	word=#hmin number 
	word=#hmax number 
	word=#hout number 
	word=#errorTol number [
		| errorTol hout hmax hmin tend tstart simData assembly |
		errorTol := stack removeLast.
		hout := stack removeLast.
		hmax := stack removeLast.
		hmin := stack removeLast.
		tend := stack removeLast.
		tstart := stack removeLast.
		simData := stack removeLast.
		assembly := stack removeLast.
		simData tstart: tstart; tend: tend; hmin: hmin; hmax: hmax; hout: hout; errorTol: errorTol.
		assembly aSimulationData: simData.
		assembly]</body>

<body package="CADSM-UI" selector="Sketch">Sketch =
	word=#Sketch [Sketch new]
	Name
	RefFrame
	Graphics</body>

<body package="CADSM-UI" selector="TimeSeries">TimeSeries =
	word=#TimeSeries
	word=#Number word=#Input number *
	word=#Time word=#Input signedNumber * [
		| times numbers assembly |
		times := stack removeLast.
		numbers := stack removeLast.
		assembly := stack removeLast.
		assembly timeSeries: times.
		assembly]
	PartSeries * .
	JointSeries * .
	MotionSeries * .
	GeneralConstraintSetSeries * .
	ForceTorqueSeries * .</body>

<body package="CADSM-UI" selector="TranslationMotion">TranslationMotion =
	word=#TranslationalMotion [
		CADSM.UI.GEOTranslationalMotion new]
	Name
	MotionJoint
	TranslationZ</body>

<body package="CADSM-UI" selector="TranslationZ">TranslationZ
	^(tokenType == #word and: [token = 'TranslationZ'])
		ifTrue: 
			[| motion function |
			motion := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			motion zIJ: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="TxOnI">TxOnI
	^(tokenType == #word and: [token = 'TxOnI'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque aTIeKe at: 1 put: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="TyOnI">TyOnI
	^(tokenType == #word and: [token = 'TyOnI'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque aTIeKe at: 2 put: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="TzOnI">TzOnI
	^(tokenType == #word and: [token = 'TzOnI'])
		ifTrue: 
			[| forceTorque function |
			forceTorque := stack last.
			function := StCAD.StMath.BasicUserFunction
						with: self nextString expandMacros
						myUnit: 1.0d
						units: StCAD.StMath.StMUnits new.
			forceTorque aTIeKe at: 3 put: function.
			self scanToken.
			true]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="Velocity3D">Velocity3D =
	word=#Velocity3D signedNumber signedNumber signedNumber [
		| vOfO1 vOfO2 vOfO3 refFrame vOfO |
		vOfO1 := stack removeLast.
		vOfO2 := stack removeLast.
		vOfO3 := stack removeLast.
		refFrame := stack removeLast.
		vOfO := StMFullColumn new: 3.
		vOfO at: 1 put: vOfO1.
		vOfO at: 2 put: vOfO2.
		vOfO at: 3 put: vOfO3.
		refFrame vOfO: vOfO.
		refFrame]</body>

<body package="CADSM-UI" selector="Vertices">Vertices =
	word=#Vertices
	word=#Number number *
	word=#x signedNumber *
	word=#y signedNumber * [
		| ys xs ns polyline n rfpointsf |
		ys := stack removeLast.
		xs := stack removeLast.
		ns := stack removeLast.
		polyline := stack removeLast.
		n := ns size.
		(xs size = n and: [ys size = n]) 
			ifFalse: [self notify: 'Some vertices are not valid.'.].
		rfpointsf := ns class new: n.
		1 to: n do: [:i | rfpointsf at: i put: (StMFullColumn with: (xs at: i) with: (ys at: i) with: 0.0d)].
		polyline rfpointsf: rfpointsf.
		polyline calc.
		polyline privateCalcBoundingBox.
		polyline]</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser</class-id> <category>error handling</category>

<body package="CADSM-UI" selector="expected:">expected: aString 
	"Notify a problem at token 'here'"

	^self notify: aString , ' expected -&gt;' at: mark</body>

<body package="CADSM-UI" selector="notify:">notify: aString 
	"Notify problem at token starting 'here'"

	^self notify: aString at: mark</body>
</methods>

<methods>
<class-id>CADSM.UI.ASMTextParser class</class-id> <category>class initialization</category>

<body package="CADSM-UI" selector="initialize">initialize
	"CADSM.UI.ASMTextParser initialize."

	| block |
	NameToGEOdict := IdentityDictionary new.
	block := 
			[:class | 
			class subclasses isEmpty 
				ifTrue: 
					[| symbol |
					symbol := class nameString asSymbol.
					(NameToGEOdict at: symbol ifAbsent: nil) isNil 
						ifTrue: [NameToGEOdict at: symbol put: class]
						ifFalse: [self halt]]
				ifFalse: [class subclasses do: [:subclass | block value: subclass]]].
	CADSM.Geo.CADSMGeoRelativeConstraintSet subclasses 
		do: [:subclass | block value: subclass].
	CADSM.Geo.CADSMGeoForceTorque subclasses 
		do: [:subclass | block value: subclass].
	^NameToGEOdict</body>
</methods>

<methods>
<class-id>CADSM.UI.ApplicationModel</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="adaptorFor:">adaptorFor: aspect 
	^(AspectAdaptor subjectChannel: self subject)
		forAspect: aspect</body>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	adButton := StCAD.StDoc.AdButton new</body>
</methods>

<methods>
<class-id>CADSM.UI.ApplicationModel</class-id> <category>validation</category>

<body package="CADSM-UI" selector="validateDouble:">validateDouble: aController 
	| array |
	array := #(-1.0d100 #&lt; #double #&lt; 1.0d100) copy.
	array at: 3 put: aController.
	^self validateDoubleWithArguments: array</body>

<body package="CADSM-UI" selector="validateDoubleGreaterThanZero:">validateDoubleGreaterThanZero: aController 
	| array |
	array := #(0.0d #&lt; #double #&lt; 1.0d100) copy.
	array at: 3 put: aController.
	^self validateDoubleWithArguments: array</body>

<body package="CADSM-UI" selector="validateDoubleWithArguments:">validateDoubleWithArguments: array 
	| lowerLimit lowerOp aController upperOp upperLimit entry |
	lowerLimit := array at: 1.
	lowerOp := array at: 2.
	aController := array at: 3.
	upperOp := array at: 4.
	upperLimit := array at: 5.
	(aController hasEditValue
		and: 
			[entry := aController editValue.
			entry isKindOf: Number])
		ifTrue: 
			[entry := entry asPrettyDouble.
			aController selectEntireText; deselect; replaceSelectionWith: entry printString; select]
		ifFalse: 
			[aController selectEntireText.
			Dialog warn: 'Enter a number like -5 or -5.5 or -55.555d-55.'.
			^false].
	(lowerLimit perform: lowerOp with: entry)
		&amp; (entry perform: upperOp with: upperLimit)
		ifFalse: 
			[aController selectEntireText.
			Dialog warn: ('Enter a number such that &lt;n&gt;&lt;1p&gt; &lt;2s&gt; number &lt;4s&gt; &lt;5p&gt; ' expandMacrosWithArguments: array).
			^false].
	^true</body>

<body package="CADSM-UI" selector="validateDoubleZeroAndGreater:">validateDoubleZeroAndGreater: aController 
	| array |
	array := #(0.0d #&lt;= #double #&lt; 1.0d100) copy.
	array at: 3 put: aController.
	^self validateDoubleWithArguments: array</body>

<body package="CADSM-UI" selector="validateIntegerWithArguments:">validateIntegerWithArguments: array 
	| lowerLimit lowerOp aController upperOp upperLimit entry |
	lowerLimit := array at: 1.
	lowerOp := array at: 2.
	aController := array at: 3.
	upperOp := array at: 4.
	upperLimit := array at: 5.
	(aController hasEditValue
		and: 
			[entry := aController editValue.
			entry isInteger])
		ifFalse: 
			[Dialog warn: 'Enter an integer.'.
			^false].
	(lowerLimit perform: lowerOp with: entry)
		&amp; (entry perform: upperOp with: upperLimit)
		ifFalse: 
			[Dialog warn: 'Enter an integer such that ' , lowerLimit printString , ' ' , lowerOp , ' integer ' , upperOp , ' ' , upperLimit printString , '.'.
			^false].
	^true</body>
</methods>

<methods>
<class-id>CADSM.UI.ApplicationModel</class-id> <category>binding</category>

<body package="CADSM-UI" selector="labelFor:">labelFor: aKey 
	"Return an instance of a non-abstract subclass of CharacterArray, 
	that will be used as a label for a widget. Check the label registry 
	if no implementation has been provided."

	^[self perform: aKey]
		on: self application messageNotUnderstoodSignal
		do: 
			[:ex | 
			| sel |
			sel := ex parameter selector.
			sel == aKey
				ifTrue: [ex return: (self application labelFor: aKey)]
				ifFalse: [ex pass]]</body>

<body package="CADSM-UI" selector="visualFor:">visualFor: aKey 
	"Return an instance of any non-abstract subclass of 
	VisualComponent (in practice usually either ComposedText or 
	Image) for use as a label for a widget."

	^[self perform: aKey]
		on: self application messageNotUnderstoodSignal
		do: 
			[:ex | 
			| sel |
			sel := ex parameter selector.
			sel == aKey
				ifTrue: [ex return: (self application visualFor: aKey)]
				ifFalse: [ex pass]]</body>
</methods>

<methods>
<class-id>CADSM.UI.ApplicationModel</class-id> <category>ad</category>

<body package="CADSM-UI" selector="adButton">adButton
	^adButton</body>

<body package="CADSM-UI" selector="adOpportunity">adOpportunity
	self changeAdxxxBy32.
	self changeAdTitle</body>

<body package="CADSM-UI" selector="adTitle">adTitle
	^StCAD.StDoc.AdData adTitle title</body>

<body package="CADSM-UI" selector="changeAdTitle">changeAdTitle
	"Do nothing."</body>

<body package="CADSM-UI" selector="changeAdxxxBy32">changeAdxxxBy32
	adButton changeAdxxxBy32</body>
</methods>

<methods>
<class-id>CADSM.UI.ApplicationModel class</class-id> <category>documentation</category>

<body package="CADSM-UI" selector="docCADCoordinateSystems">docCADCoordinateSystems
	"
	GEOItem is always in SI units (Double). 
	CADDrawing is always in pixel units (Integer). 
	Drawing origin and axes coincides with projection frame origin and axes. 
	x axis is to right. y axis is down. 
	Projection frame converts world coordinates to drawing coordinates with scale (pixelPerMetre) change 
	only. 
	ScrollArea uses positive x and y only (Integers). Therefore Drawing origin is offset from ScrollArea 
	origin. 
	Pixmap is the visible pane area. It uses positive x and y only (Integers). Therefore Drawing 
	origin is offset from Pixmap origin. 
	But Pixmap and Drawing axes coincide. 
	Drawing and pixmap use integer math only. 
	
	Transform: 
	(O) World &gt; (P)rojectionFrame &gt; (D)rawing &gt; (S)crollArea 
	(O) World &gt; (P)rojectionFrame &gt; (D)rawing &gt; Pixmap 
	rOpO (Double) &gt; rPpP (Double) &gt; rDpPx (Integer) &gt; rSpPx (Integer). 
	rOpO is oriented and translated to rPpP. 
	rPpP is scaled only to rDpPx. 
	rDpPx is translated only to rSpPx. 
	rPpP := aAOPT*(rOpO - rOPO). 
	rDpPx := (rPpP - rPDP) / sPD := rDPD + sDP*rPpP := rPpP / sPD := sDP*rPpP. 
	rSpPx := (rDpPx - rDSPx) / sDS := rSDPx + sSD*rDpPx := (rDpPx - rDSPx) := (rSDPx + rDpPx). 
	
	Transform: 
	(S)crollArea &gt; (D)rawing &gt; (P)rojectionFrame &gt; (O) World. 
	rSpPx &gt; rDpPx &gt; rPpP &gt; rOpO. 
	rSpPx := displacement from ScrollArea origin to point p in ScrollArea (pixel) coordinates. 
	rSDPx := displacement from ScrollArea origin to Drawing origin in ScrollArea (pixel) coordinates. 
	rDpPx := (rSpPx - rSDPx) / sSD := rDSPx + sDS*rSpPx := rSpPx - rSDPx := rDSPx + rSpPx. 
	rPpP := (rDpPx - rDPD) / sDP := rPDP + sPD*rDpPx := rDpPx / sDP := sPD*rDpPx. 
	With an arbitrary zPpP: 
	rOpO := rOPO + aAOP*rPpP 
	"

	self commentOnly</body>

<body package="CADSM-UI" selector="docCADCoordinateSystems1">docCADCoordinateSystems1
	"
	GEOItem is always in SI units (Double). 
	CADDrawing is always in pixel units (Integer). 
	Drawing origin and axes coincides with projection frame origin and axes. 
	x axis is to right. y axis is down. 
	Projection frame converts world coordinates to drawing coordinates with scale (pixelPerMetre) change 
	only. 
	CADPixmap uses positive x and y only (Integers). Therefore Drawing origin is offset from Pixmap 
	origin. 
	But Pixmap and Drawing axes coincide. 
	Drawing and pixmap use integer math only. 
	
	Transform: 
	(O) World &gt; (P)rojectionFrame &gt; (D)rawing &gt; (S)creen 
	rOpO (Double) &gt; rPpP (Double) &gt; rDpD (Integer) &gt; rSpS (Integer). 
	rOpO is oriented and translated to rPpP. 
	rPpP is scaled only to rDpD. 
	rDpD is translated only to rSpS. 
	rPpP := aAOPT*(rOpO - rOPO). 
	rDpD := (rPpP - rPDP) / sPD := rDPD + sDP*rPpP := rPpP / sPD := sDP*rPpP. 
	rSpS := (rDpD - rDSD) / sDS := rSDS + sSD*rDpD := (rDpD - rDSD) := (rSDS + rDpD). 
	
	Transform: 
	(S)creen &gt; (D)rawing &gt; (P)rojectionFrame &gt; (O) World. 
	rSpS &gt; rDpD &gt; rPpP &gt; rOpO. 
	rSpS := displacement from Screen origin to point p in Screen (pixel) coordinates. 
	rSDS := displacement from Screen origin to Drawing origin in Screen (pixel) coordinates. 
	rDpD := (rSpS - rSDS) / sSD := rDSD + sDS*rSpS := rSpS - rSDS := rDSD + rSpS. 
	rPpP := (rDpD - rDPD) / sDP := rPDP + sPD*rDpD := rDpD / sDP := sPD*rDpD. 
	With an arbitrary zPpP: 
	rOpO := rOPO + aAOP*rPpP 
	"

	self commentOnly</body>

<body package="CADSM-UI" selector="docGEOCoordinateSystems">docGEOCoordinateSystems
	"
	GEOItem is always in SI units (Double). 
	
	Transform: 
	(O) World &gt; (A) Assembly &gt; (P) Part &gt; (Sk) Sketch &gt; (G) Graphics &gt; (E) GraphicElement 
	(O) World &gt; (A) Assembly &gt; (P) Part &gt; (Sk) Sketch &gt; GEOLine 

	(O) World &gt; (A) Assembly &gt; (P) Part &gt; (G) Graphics &gt; (E) GraphicElement 
	(O) World &gt; (A) Assembly &gt; (P) Part &gt; GEOLine 
	
	"

	self commentOnly</body>

<body package="CADSM-UI" selector="docPrinciples">docPrinciples
	"
	Create part. 
	_ Insert sketch. 
	_ _ Line, polyline, circle. 
	_ _ Variational constraints on graphic elements. 
	_ Extrude or revolve. 
	"
	"
	Create assembly. 
	_ Insert parts and/or assemblys. 
	_ Create additional parts and/or assemblys. 
	_ Assembly constraints on parts. 
	_ Do dynamics. 
	_ _ Add masses, moment of inertias, motions, forces. 
	_ _ Add integration parameters. 
	_ _ Simulate, animate, plot. 
	"

	self commentOnly</body>

<body package="CADSM-UI" selector="docTiltAndRotate">docTiltAndRotate
	"
	Tilt is the angle away from the normal to the screen. 
	Rotate is the spin about the normal to the screen. 
	Where to select the pivot point? 
	_ Origin of world frame, assembly frame, part frame, sketch frame or element frame. 
	_ Center of 3D object. 
	_ User selected corner. 
	When pivot point is selected: 
	_ Pan screen to so that pivot point is at center of screen. 
	_ For tilt: 
	_ _ Initialize a handle over pivot point. 
	_ _ Draw concentric circles for 90deg and 180deg. 
	_ _ Tilt away from pivot point in direction of cursor. 
	_ For rotate: 
	_ _ Draw reference line from pivot and parallel to x axis. 
	_ _ Initialize a handle at a point on the reference line. 
	_ _ Counter clockwise is positive. 
	
	Rotate frame f to f'. Let 
	rFpvF := pivot point in reference frame (F) of f. 
	n := direction of rotation axis. 
	theta := right rotation about n. 
	Define euler parameters: 
	E1 := nx*sin(theta/2). 
	E2 := ny*sin(theta/2). 
	E3 := nz*sin(theta/2). 
	E4 := cos(theta/2). 
	Form transformation matrix aAff' from euler parameters. 
	rFfF := origin of f before rotation. 
	rFf'F := origin of f after rotation. 
	rFf'F := rFfvF + aAff'T*(rFfF - rFpvF). 
	aAOf' := aAOf*aAff' 
	"

	self commentOnly</body>

<body package="CADSM-UI" selector="readMe">readMe
	"
	StCAD is an attempt to bring 3D CAD capabilities to Smalltalk. It can then be the front end of 
	many engineering/scientific applications. 
	
	I will enhance and document based on user feedback. Please email your comments and 
	improvements to me. 
	
	Sincerely, 
	Aik-Siong Koh 
	askoh@alumni.princeton.edu 
	"

	self commentOnly</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aMediator">aMediator
	^aMediator</body>

<body package="CADSM-UI" selector="aMediator:">aMediator: anObject 
	aMediator := anObject</body>

<body package="CADSM-UI" selector="aTool">aTool
	^aMediator aTool</body>

<body package="CADSM-UI" selector="buttonState">buttonState
	^#pick</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	aMediator := CADSMUIMediator new.
	aMediator aEditor: self.
	self cadView aCamera: (aMediator aGeoUniverse cCamera at: 1)</body>

<body package="CADSM-UI" selector="postBuildWith:">postBuildWith: aBuilder 
	builder window application: self.
	self aMediator when: #select
		do: [self selectionValue: aMediator selections asArray].
	self aMediator when: #deselect
		do: [self selectionValue: aMediator selections asArray].
	self aMediator 
		when: #mousePointChanged
		ask: self
		perform: #rDcursorPxValue:.
	self aMediator 
		when: #handleInvoked
		ask: self
		perform: #handleValue:.
	self aMediator 
		when: #noHandleInvoked
		ask: self
		perform: #clearHandleValue.
	self treeView list root: CADSMUITreeNode new displayIt: true.
	self treeView selectionIndexHolder 
		onChangeSend: #updateCadViewFromTreeView
		to: self.
	self aMediator 
		when: #select
		ask: self
		perform: #updateTreeViewFromCadView</body>

<body package="CADSM-UI" selector="updateCadViewFromTreeView">updateCadViewFromTreeView</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>aspects</category>

<body package="CADSM-UI" selector="cadView">cadView
	^cadView isNil 
		ifTrue: [cadView := OpenGLView model: self]
		ifFalse: [cadView]</body>

<body package="CADSM-UI" selector="doubleClick:">doubleClick: aTreeController 
	"Let the tree toggle the state of expandation of the selected node."

	aTreeController toggleExpand</body>

<body package="CADSM-UI" selector="selection">selection
	"This method was generated by UIDefiner.  Any edits made here
	may be lost whenever methods are automatically defined.  The
	initialization provided below may have been preempted by an
	initialize method."

	^selection isNil
		ifTrue:
			[selection := String new asValue]
		ifFalse:
			[selection]</body>

<body package="CADSM-UI" selector="selectionValue:">selectionValue: cadGO 
	self selection value: cadGO printString</body>

<body package="CADSM-UI" selector="treeView">treeView
	"This method was generated by UIDefiner.  Any edits made here
	may be lost whenever methods are automatically defined.  The
	initialization provided below may have been preempted by an
	initialize method."

	^treeView isNil
		ifTrue:
			[treeView := SelectionInTree new]
		ifFalse:
			[treeView]</body>

<body package="CADSM-UI" selector="updateTreeModel:">updateTreeModel: controller 
	| newRoot treeModel originalRoot |
	newRoot := aMediator aGeoUniverse isNil 
				ifTrue: [StCAD.StGeo.GEOTreeNode new]
				ifFalse: [aMediator aGeoUniverse asTreeNode].
	treeModel := self treeView list.
	originalRoot := treeModel at: 1.
	originalRoot copyFrom: newRoot.
	treeModel refreshRoot.
	treeModel expand: 1</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	aMediator renderOn: aRenderingContext</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>ad</category>

<body package="CADSM-UI" selector="changeAdTitle">changeAdTitle
	self mainWindow 
		label: 'CADSM     ' , aMediator aFilename asString , '          ' 
				, self adTitle</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>menubar items</category>

<body package="CADSM-UI" selector="menuFileOpenAssembly">menuFileOpenAssembly
	self changeRequest ifTrue: [aMediator menuFileOpenAssembly]</body>

<body package="CADSM-UI" selector="menuInspect">menuInspect
	self inspect</body>

<body package="CADSM-UI" selector="menuViewPresentationHideLine">menuViewPresentationHideLine
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator menuViewPresentationHideLine.
			cadView invalidate.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="menuViewPresentationSolid">menuViewPresentationSolid
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator menuViewPresentationSolid.
			cadView invalidate.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="menuViewPresentationWireframe">menuViewPresentationWireframe
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator menuViewPresentationWireframe.
			cadView invalidate.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="menuViewTiltRotateUniverse">menuViewTiltRotateUniverse
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator doTiltRotateUniverseInView: cadView.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="menuViewYupQuadmpm">menuViewYupQuadmpm
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator doYupQuadmpmInView: cadView.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="menuViewYupXright">menuViewYupXright
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator doYupXrightInView: cadView.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="menuViewZoomIn">menuViewZoomIn
	self changeRequest ifTrue: [aMediator doZoomIn]</body>

<body package="CADSM-UI" selector="menuViewZupQuadmmp">menuViewZupQuadmmp
	self changeRequest 
		ifTrue: 
			[self adOpportunity.
			aMediator doZupQuadmmpInView: cadView.
			self triggerEvent: #projection]</body>

<body package="CADSM-UI" selector="scroll:">scroll: aPoint 
	aMediator scrollView: cadView by: aPoint</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor</class-id> <category>As yet unclassified</category>

<body package="CADSM-UI" selector="animationWindow">animationWindow
	^self dependents detect: 
			[:dependent | 
			(dependent isKindOf: ApplicationWindow) 
				and: [dependent model isMemberOf: Animation]]
		ifNone: nil</body>

<body package="CADSM-UI" selector="animationWindowRaise">animationWindowRaise
	| selfWindow animationWindow animationBuilder |
	animationWindow := self animationWindow.
	animationWindow isNil 
		ifTrue: 
			[animationBuilder := Animation openOn: aMediator.
			animationBuilder notNil 
				ifTrue: 
					[selfWindow := builder window.
					animationWindow := animationBuilder window.
					selfWindow application: self.
					animationWindow application: self.
					selfWindow beMaster.
					animationWindow beSlave]]
		ifFalse: 
			[animationWindow
				expand;
				raise]</body>

<body package="CADSM-UI" selector="menuSimulationAnimation">menuSimulationAnimation
	self animationWindowRaise</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="changeRequest">changeRequest
	^super changeRequest and: [animationProcess notNil
			ifTrue: 
				[Dialog warn: 'Stop animation before closing.' for: builder window.
				false]
			ifFalse: [true]]</body>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	animationData := nil asValue.
	icurrent := self adaptorFor: #icurrent.
	istart := self adaptorFor: #istart.
	iend := self adaptorFor: #iend.
	tcurrent := (AspectAdaptor subject: self)
				forAspect: #calctcurrent.
	tstart := (AspectAdaptor subject: self)
				forAspect: #calctstart.
	tend := (AspectAdaptor subject: self)
				forAspect: #calctend.
	speed := self adaptorFor: #framesPerSecond</body>

<body package="CADSM-UI" selector="open">open
	| x y |
	self allButOpenInterface: #windowSpec.
	x := Screen default bounds extent x - builder window bounds extent x - 20.
	y := 65.
	builder openAt: x @ y.
	self postOpenWith: builder.
	^builder</body>

<body package="CADSM-UI" selector="postBuildWith:">postBuildWith: aBuilder 
	icurrent onChangeSend: #changedicurrent to: self.
	istart onChangeSend: #changedistart to: self.
	iend onChangeSend: #changediend to: self</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="cadInterface:">cadInterface: interface 
	cadInterface := interface.
	timeSeries := cadInterface timeSeries.
	animationData value: cadInterface animationData</body>

<body package="CADSM-UI" selector="calctcurrent">calctcurrent
	| i |
	i := icurrent value.
	^i &gt; 0
		ifTrue: [(timeSeries at: i) printString]
		ifFalse: [animationProcess == nil
				ifTrue: ['Input State']
				ifFalse: ['Animating']]</body>

<body package="CADSM-UI" selector="calctcurrent:">calctcurrent: string 
	"Do nothing."</body>

<body package="CADSM-UI" selector="calctend">calctend
	^(timeSeries at: iend value) printString</body>

<body package="CADSM-UI" selector="calctend:">calctend: string 
	"Do nothing."</body>

<body package="CADSM-UI" selector="calctstart">calctstart
	^(timeSeries at: istart value) printString</body>

<body package="CADSM-UI" selector="calctstart:">calctstart: string 
	"Do nothing."</body>

<body package="CADSM-UI" selector="icurrent">icurrent
	^icurrent</body>

<body package="CADSM-UI" selector="iend">iend
	^iend</body>

<body package="CADSM-UI" selector="istart">istart
	^istart</body>

<body package="CADSM-UI" selector="speed">speed
	^speed</body>

<body package="CADSM-UI" selector="subject">subject
	^animationData</body>

<body package="CADSM-UI" selector="tcurrent">tcurrent
	^tcurrent</body>

<body package="CADSM-UI" selector="tend">tend
	^tend</body>

<body package="CADSM-UI" selector="tstart">tstart
	^tstart</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>change</category>

<body package="CADSM-UI" selector="changedicurrent">changedicurrent
	| i |
	self adOpportunity.
	self updatetcurrent.
	i := icurrent value.
	i &gt; 0 ifTrue: [(cadInterface canUpdateForFrame: i)
			ifTrue: [cadInterface updateForFrame: i]
			ifFalse: [Dialog warn: 'At least one part does not belong to this simulation.']]</body>

<body package="CADSM-UI" selector="changediend">changediend
	self updatetend</body>

<body package="CADSM-UI" selector="changedistart">changedistart
	self updatetstart</body>

<body package="CADSM-UI" selector="updatetcurrent">updatetcurrent
	^tcurrent value: self calctcurrent</body>

<body package="CADSM-UI" selector="updatetend">updatetend
	^tend value: self calctend</body>

<body package="CADSM-UI" selector="updatetstart">updatetstart
	^tstart value: self calctstart</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>menu items</category>

<body package="CADSM-UI" selector="menuFrameFirst">menuFrameFirst
	self isUpToDate ifTrue: [icurrent value: 1]</body>

<body package="CADSM-UI" selector="menuFrameInputState">menuFrameInputState
	self isUpToDate
		ifTrue: 
			[icurrent value: 0.
			cadInterface updateFromInputState]</body>

<body package="CADSM-UI" selector="menuFrameLast">menuFrameLast
	self isUpToDate ifTrue: [icurrent value: animationData value nframe]</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>actions</category>

<body package="CADSM-UI" selector="directionAction">directionAction
	| menu symbol |
	menu := self class directionMenu.
	animationData value isForward
		ifTrue: 
			[(menu atNameKey: #menuDirectionForwardID) beOn.
			(menu atNameKey: #menuDirectionBackwardID) beOff]
		ifFalse: 
			[(menu atNameKey: #menuDirectionForwardID) beOff.
			(menu atNameKey: #menuDirectionBackwardID) beOn].
	symbol := menu startUp.
	symbol isSymbol ifTrue: [self perform: symbol]</body>

<body package="CADSM-UI" selector="frameAction">frameAction
	| menu symbol |
	menu := self class frameMenu.
	symbol := menu startUp.
	symbol isSymbol ifTrue: [self perform: symbol]</body>

<body package="CADSM-UI" selector="menuDirectionBackward">menuDirectionBackward
	animationData value isForward: false</body>

<body package="CADSM-UI" selector="menuDirectionForward">menuDirectionForward
	animationData value isForward: true</body>

<body package="CADSM-UI" selector="play">play
	"Do not use Delay. It causes jerky animation."

	"In Linux86, high fps causes slow user interactions!!!"

	| series data nseries msStartOfAnimation msStartOfFrame |
	(self isUpToDate and: [animationProcess isNil]) 
		ifTrue: 
			[series := OrderedCollection new.
			data := animationData value.
			data istart &lt;= data iend 
				ifTrue: [data istart to: data iend do: [:i | series add: i]]
				ifFalse: 
					[data istart to: data nframe do: [:i | series add: i].
					1 to: data iend do: [:i | series add: i]].
			series := data isForward 
						ifTrue: [series asArray]
						ifFalse: [series asArray reverse].
			(cadInterface cadAnimateSeries: series) 
				ifTrue: 
					[ObjectMemory garbageCollect.
					nseries := series size.
					cadInterface hideHandles.
					msStartOfAnimation := msStartOfFrame := Time millisecondClockValue.
					animationProcess := 
							[[true] whileTrue: 
									[| msElapse msPerFrame iFrameElapse iframe |
									msElapse := Time millisecondClockValue - msStartOfAnimation.
									msPerFrame := 1000 // data framesPerSecond.	"Keep here so that fps can be 
									changes on the fly."
									iFrameElapse := msElapse // msPerFrame.
									iframe := series at: iFrameElapse \\ nseries + 1.
									cadInterface animateFrame: iframe.
									
									["This will limit the actual frame rate to 30 fps. Rapid fps seems to cause problems on Linux."

									Processor yield.
									Time millisecondClockValue - msStartOfFrame &lt; 33] 
											whileTrue.
									msStartOfFrame := Time millisecondClockValue]] 
									forkAt: Processor userBackgroundPriority.
					icurrent value: 0.
					(self builder componentAt: #icurrentID) disable]
				ifFalse: 
					[Dialog 
						warn: 'At least one part does not belong to this simulation.&lt;n&gt;Rerun simulation.' 
								expandMacros]]</body>

<body package="CADSM-UI" selector="play1">play1
	"Do not use Delay. It causes jerky animation."

	| series data nseries count msStartOfFrame |
	(self isUpToDate and: [animationProcess isNil])
		ifTrue: 
			[series := OrderedCollection new.
			data := animationData value.
			data istart &lt;= data iend
				ifTrue: [data istart to: data iend do: [:i | series add: i]]
				ifFalse: 
					[data istart to: data nframe do: [:i | series add: i].
					1 to: data iend do: [:i | series add: i]].
			series := data isForward
						ifTrue: [series asArray]
						ifFalse: [series asArray reverse].
			(cadInterface cadAnimateSeries: series)
				ifTrue: 
					[ObjectMemory garbageCollect.
					nseries := series size.
					cadInterface hideHandles.
					count := 0.
					msStartOfFrame := Time millisecondClockValue.
					animationProcess := [[true]
								whileTrue: 
									[| iframe msPerFrame msStartOfNextFrame |
									iframe := series at: count \\ nseries + 1.
									cadInterface animateFrame: iframe.
									count := count + 1.
									msPerFrame := 1000 // data framesPerSecond.
									msStartOfNextFrame := msStartOfFrame + msPerFrame.
									
									[Processor yield.
									Time millisecondClockValue &lt; msStartOfNextFrame] whileTrue.
									msStartOfFrame := Time millisecondClockValue]]
								forkAt: Processor userBackgroundPriority.
					icurrent value: 0.
					(self builder componentAt: #icurrentID) disable]
				ifFalse: [Dialog warn: 'At least one part does not belong to this simulation.']]</body>

<body package="CADSM-UI" selector="play2">play2
	"Do not use Delay. It causes jerky animation."

	| series data nseries msStartOfFrame |
	(self isUpToDate and: [animationProcess isNil])
		ifTrue: 
			[series := OrderedCollection new.
			data := animationData value.
			data istart &lt;= data iend
				ifTrue: [data istart to: data iend do: [:i | series add: i]]
				ifFalse: 
					[data istart to: data nframe do: [:i | series add: i].
					1 to: data iend do: [:i | series add: i]].
			series := data isForward
						ifTrue: [series asArray]
						ifFalse: [series asArray reverse].
			(cadInterface cadAnimateSeries: series)
				ifTrue: 
					[ObjectMemory garbageCollect.
					nseries := series size.
					cadInterface hideHandles.
					msStartOfFrame := Time millisecondClockValue.
					animationProcess := [[true]
								whileTrue: 
									[| msElapse msPerFrame iFrameElapse iframe |
									msElapse := Time millisecondClockValue - msStartOfFrame.
									msPerFrame := 1000 // data framesPerSecond.	"Keep here so that fps can be 
									changes on the fly."
									iFrameElapse := msElapse // msPerFrame.
									iframe := series at: iFrameElapse \\ nseries + 1.
									cadInterface animateFrame: iframe.
									Processor yield]]
								forkAt: Processor userBackgroundPriority.
					icurrent value: 0.
					(self builder componentAt: #icurrentID) disable]
				ifFalse: [Dialog warn: 'At least one part does not belong to this simulation.']]</body>

<body package="CADSM-UI" selector="step">step
	| data increment iframe |
	self isUpToDate
		ifTrue: 
			[data := animationData value.
			increment := data isForward
						ifTrue: [1]
						ifFalse: [-1].
			iframe := icurrent value + increment.
			iframe := iframe - 1 \\ data nframe + 1.
			icurrent value: iframe]</body>

<body package="CADSM-UI" selector="stop">stop
	"The garbage can cursor persists when this command is executed during garbage collection."
	"'Cursor normal show' forces a normal cursor."

	| sem |
	animationProcess == nil
		ifFalse: 
			[sem := Semaphore new.
			
			[animationProcess terminate.
			animationProcess := nil.
			sem signal]
				forkAt: animationProcess priority.
			sem wait.
			Cursor normal show.
			(self builder componentAt: #icurrentID) enable.
			icurrent value: animationData value istart.
			cadInterface unhideHandles]</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>validation</category>

<body package="CADSM-UI" selector="validateRange:">validateRange: aController 
	| array |
	^self isUpToDate
		ifTrue: 
			[array := Array new: 5.
			array at: 1 put: 1.
			array at: 2 put: #&lt;=.
			array at: 3 put: aController.
			array at: 4 put: #&lt;=.
			array at: 5 put: animationData value nframe.
			self validateIntegerWithArguments: array]
		ifFalse: [false]</body>

<body package="CADSM-UI" selector="validateSpeed:">validateSpeed: aController 
	| array |
	array := Array new: 5.
	array at: 1 put: 1.
	array at: 2 put: #&lt;=.
	array at: 3 put: aController.
	array at: 4 put: #&lt;=.
	array at: 5 put: 10000.
	^self validateIntegerWithArguments: array</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>testing</category>

<body package="CADSM-UI" selector="isUpToDate">isUpToDate
	^cadInterface timeSeries notNil
		ifTrue: 
			[animationData value == cadInterface animationData
				ifFalse: 
					[timeSeries := cadInterface timeSeries.
					animationData value: cadInterface animationData].
			true]
		ifFalse: 
			[Dialog warn: 'Assembly has no simulation data.'.
			self closeAndUnschedule.
			false]</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation</class-id> <category>ad</category>

<body package="CADSM-UI" selector="adOpportunity">adOpportunity
	super adOpportunity.
	cadInterface cadApp adOpportunity</body>

<body package="CADSM-UI" selector="changeAdTitle">changeAdTitle
	self builder window label: 'CADSM Animation' , '          ' , self adTitle</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation class</class-id> <category>instance creation</category>

<body package="CADSM-UI" selector="openOn:">openOn: cadInterface 
	| newDialog |
	^(cadInterface geoRootItem notNil and: 
			[cadInterface timeSeries notNil and: [cadInterface timeSeries isEmpty not]]) 
		ifTrue: 
			[newDialog := super new.
			newDialog cadInterface: cadInterface.
			newDialog open]
		ifFalse: 
			[Dialog warn: 'Assembly has no simulation data.'.
			nil]</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUITool</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aMediator">aMediator
	^aMediator</body>

<body package="CADSM-UI" selector="aMediator:">aMediator: anObject 
	aMediator := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUITool class</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="stockIconFor:">stockIconFor: aString 
	self notYetImplemented.
	^nil</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUISelectionTool</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="selectionTracker">selectionTracker
	^(SelectionToolTracker new)
		aTool: self;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUISelectionTool</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	name := 'Selection'.
	aIcon := nil.
	aCursor := Cursor normal</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRetainedMedium</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="bounds">bounds
	^0 @ 0 extent: extent</body>

<body package="CADSM-UI" selector="calcViewBoxFor:with:">calcViewBoxFor: aBoundingBox with: projection 
	^self renderingContext calcViewBoxFor: aBoundingBox with: projection</body>

<body package="CADSM-UI" selector="renderingContext">renderingContext
	^OpenGLRenderingContext on: self</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRetainedMedium</class-id> <category>testing</category>

<body package="CADSM-UI" selector="isOpenGL">isOpenGL
	^true</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRetainedMedium</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="makeCamera:fit:">makeCamera: aCamera fit: aBoundingBox 
	| aCameraRefFrame aBoundingBoxC height distance rOfocusO rOeyeO |
	aCameraRefFrame := aCamera aRefFrame.
	aBoundingBoxC := aBoundingBox inRefFrame: aCameraRefFrame.
	height := 1.25d * aBoundingBoxC extent y.
	distance := aCamera ratio * height.
	rOfocusO := aBoundingBox center.
	rOeyeO := rOfocusO 
				plusFullColumn: (aCameraRefFrame aAOf timesFullColumn: (StMFullColumn 
								with: 0.0d
								with: 0.0d
								with: distance)).
	aCamera eyePoint: rOeyeO.
	aCamera distance: distance.
	aCamera height: height</body>

<body package="CADSM-UI" selector="scrollCamera:by:">scrollCamera: aCamera by: aPoint 
	self renderingContext scrollCamera: aCamera by: aPoint</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLDisplayController</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aOpenGLPointFor:">aOpenGLPointFor: eventOrPoint 
	| rvSTpvST rvGLpvGL |
	rvSTpvST := (eventOrPoint isKindOf: MouseButtonEvent) 
				ifTrue: [self sensor mousePointFor: eventOrPoint]
				ifFalse: [eventOrPoint].
	rvGLpvGL := rvSTpvST x @ (view bounds extent y - 1 - rvSTpvST y).
	^rvGLpvGL</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLDisplayController</class-id> <category>events</category>

<body package="CADSM-UI" selector="redButtonPressedEvent1:">redButtonPressedEvent1: event 
	| rvSTpvST rvGLpvGL pickedObject |
	rvSTpvST := self sensor mousePointFor: event.
	rvGLpvGL := rvSTpvST x @ (view bounds extent y - 1 - rvSTpvST y).
	pickedObject := view pickAt: rvGLpvGL.
	pickedObject ifNotNil: [pickedObject selectionTracker handleEvent: event].
	view keyboardProcessor 
		ifNotNil: [:keyboardProcessor | keyboardProcessor requestActivationFor: self]</body>

<body package="CADSM-UI" selector="redButtonPressedEvent:">redButtonPressedEvent: event 
	| rvSTpvST rvGLpvGL |
	rvSTpvST := self sensor mousePointFor: event.
	rvGLpvGL := rvSTpvST x @ (view bounds extent y - 1 - rvSTpvST y).
	(((view pickHandleAt: rvGLpvGL) ifNil: [self model aTool]) 
		selectionTracker)
		setController: self;
		redButtonPressedEvent: event.
	view keyboardProcessor 
		ifNotNil: [:keyboardProcessor | keyboardProcessor requestActivationFor: self]</body>
</methods>

<methods>
<class-id>CADSM.UI.ToolTracker</class-id> <category>private</category>

<body package="CADSM-UI" selector="setUpFor:">setUpFor: aMouseButtonEvent 
	rvFirstv := controller aOpenGLPointFor: aMouseButtonEvent</body>
</methods>

<methods>
<class-id>CADSM.UI.SelectionToolTracker</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aTool">aTool
	^aTool</body>

<body package="CADSM-UI" selector="aTool:">aTool: anObject
	aTool := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.SelectionToolTracker</class-id> <category>private</category>

<body package="CADSM-UI" selector="doSelectionTrackingOperationAt:">doSelectionTrackingOperationAt: rvSTpvST 
	| view rvGLpvGL |
	view := self controller view.
	rvGLpvGL := rvSTpvST x @ (view bounds extent y - 1 - rvSTpvST y).
	view displaySelectionTrackingFrom: rvFirstv to: rvGLpvGL</body>

<body package="CADSM-UI" selector="finishSelectionFor:">finishSelectionFor: aPoint 
	| rect face edge vertex |
	self halt.
	rect := Graphics.Rectangle origin: rvFirstv corner: aPoint.
	face := self pickFaceInRect: rect.
	edge := self pickEdgeInFace: face inRect: rect.
	vertex := self pickVertexInEdge: edge inRect: rect.
	super finishSelectionFor: aPoint</body>
</methods>

<methods>
<class-id>CADSM.UI.RefFrameTracker</class-id> <category>private</category>

<body package="CADSM-UI" selector="finishSelectionFor:">finishSelectionFor: aPoint 
	super finishSelectionFor: aPoint</body>

<body package="CADSM-UI" selector="setUpFor:">setUpFor: aMouseButtonEvent 
	frozenFrame := aFrame frozenCopy.
	rvFirstv := controller aOpenGLPointFor: aMouseButtonEvent.
	rvOldv := rvFirstv copy</body>
</methods>

<methods>
<class-id>CADSM.UI.RefFrameTracker</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aFrame">aFrame
	^aFrame</body>

<body package="CADSM-UI" selector="aFrame:">aFrame: anObject
	aFrame := anObject</body>

<body package="CADSM-UI" selector="direction">direction
	^direction</body>

<body package="CADSM-UI" selector="direction:">direction: anObject
	direction := anObject</body>

<body package="CADSM-UI" selector="rFcenterF">rFcenterF
	^rFcenterF</body>

<body package="CADSM-UI" selector="rFcenterF:">rFcenterF: anObject
	rFcenterF := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.TiltTracker</class-id> <category>private</category>

<body package="CADSM-UI" selector="doSelectionTrackingOperationAt:">doSelectionTrackingOperationAt: rvNewv 
	| radialVector |
	radialVector := (controller aOpenGLPointFor: rvNewv) - rvFirstv.
	radialVector isZero 
		ifFalse: 
			[| pixelPerDegree aView rvtiltv rCtiltC aCameraFrame aAOC aAFC rFtiltF thetaF newFrame |
			pixelPerDegree := 1.
			aView := aHandle aView.
			rvtiltv := radialVector y negated @ radialVector x.
			rCtiltC := aView rCpCfromrvpv: rvtiltv.
			aCameraFrame := aView aCamera aRefFrame.
			aAOC := aFrame == aCameraFrame 
						ifTrue: [frozenFrame aAOf]
						ifFalse: [aCameraFrame aAOf].
			aAFC := frozenFrame aAOF transpose timesFullMatrix: aAOC.
			rFtiltF := aAFC timesFullColumn: rCtiltC.
			thetaF := (radialVector r / pixelPerDegree) degreesToRadians.
			newFrame := frozenFrame copy.
			newFrame 
				rotateAt_rFpvF: rFcenterF
				axisF: rFtiltF
				theta: thetaF * direction.
			aFrame copyrFfFandAFfFrom: newFrame.
			aView calcBoundsAndRedisplay: aHandle aSpatialItem]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aCamera">aCamera
	^aCamera</body>

<body package="CADSM-UI" selector="aCamera:">aCamera: anObject
	aCamera := anObject</body>

<body package="CADSM-UI" selector="addHandle:">addHandle: aHandle 
	cHandle add: aHandle.
	aHandle aView: self</body>

<body package="CADSM-UI" selector="cachedBitmap:">cachedBitmap: aBoolean</body>

<body package="CADSM-UI" selector="clearcHandle">clearcHandle
	cHandle := CADSM.Misc.CADSMMiscOrderedSet new</body>

<body package="CADSM-UI" selector="keyboardProcessor">keyboardProcessor
	^self topComponent keyboardProcessor</body>

<body package="CADSM-UI" selector="preferredBounds:">preferredBounds: anObject
	preferredBounds := anObject</body>

<body package="CADSM-UI" selector="rCpCfromrvpv:">rCpCfromrvpv: rvtiltv 
	| rCtiltC |
	rCtiltC := aCamera height * rvtiltv / cachedBitmap extent y.
	^StMFullColumn 
		with: rCtiltC x
		with: rCtiltC y
		with: 0.0d</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>converting</category>

<body package="CADSM-UI" selector="asBitmap">asBitmap
	| renderingContext |
	self 
		assert: [renderingContext := self renderingContext]
		do: 
			[self renderOn: renderingContext.
			renderingContext flush]
		ensure: [renderingContext release].
	^self cachedBitmap</body>

<body package="CADSM-UI" selector="asImage">asImage
	^self asBitmap medium asImage</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>evaluating</category>

<body package="CADSM-UI" selector="assert:do:ensure:">assert: assertBlock do: doBlock ensure: ensureBlock 
	assertBlock value.
	[doBlock value]
		ensure: [ensureBlock value]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>bounds accessing</category>

<body package="CADSM-UI" selector="bounds:">bounds: newBounds 
	super bounds: newBounds.
	self flushCachedBitmap.
	self model changed: #value</body>

<body package="CADSM-UI" selector="calcViewBoxFor:">calcViewBoxFor: aJun3dBoundingBox 
	| aBitmap |
	aBitmap := self cachedBitmap.
	^aBitmap calcViewBoxFor: aJun3dBoundingBox with: aCamera</body>

<body package="CADSM-UI" selector="preferredBounds">preferredBounds
	^preferredBounds notNil 
		ifTrue: [preferredBounds]
		ifFalse: [super preferredBounds]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>private</category>

<body package="CADSM-UI" selector="cachedBitmap">cachedBitmap
	cachedBitmap isNil ifTrue: [self createBitmap].
	^cachedBitmap</body>

<body package="CADSM-UI" selector="createBitmap">createBitmap
	cachedBitmap := OpenGLRetainedMedium extent: self bounds extent.
	cachedBitmap setBackground: self lookPreferences backgroundColor.
	^cachedBitmap</body>

<body package="CADSM-UI" selector="fit:">fit: aBoundingBox 
	self cachedBitmap makeCamera: aCamera fit: aBoundingBox.
	preferredBounds origin: 0 @ 0 corner: 1 @ 1</body>

<body package="CADSM-UI" selector="flushCachedBitmap">flushCachedBitmap
	self flushCachedRenderingContext.
	cachedBitmap notNil ifTrue: [bitmapSemaphore critical: [cachedBitmap release]].
	cachedBitmap := nil</body>

<body package="CADSM-UI" selector="flushCachedRenderingContext">flushCachedRenderingContext
	cachedRenderingContext notNil ifTrue: [cachedRenderingContext release].
	cachedRenderingContext := nil.
	displayListHolder := nil</body>

<body package="CADSM-UI" selector="scroll:">scroll: aPoint 
	model scroll: aPoint.
	^aPoint</body>

<body package="CADSM-UI" selector="scrollCameraBy:">scrollCameraBy: aPoint 
	self cachedBitmap scrollCamera: aCamera by: aPoint</body>

<body package="CADSM-UI" selector="scrollProjector:by:">scrollProjector: displayProjector by: aPoint 
	self cachedBitmap scrollProjector: displayProjector by: aPoint</body>

<body package="CADSM-UI" selector="viewportInMedium">viewportInMedium
	| rect |
	rect := self bounds translatedBy: (self localPointToGlobal: Point zero).
	^rect</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>debug</category>

<body package="CADSM-UI" selector="debug:">debug: aBlock 
	"aBlock value"</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>controller accessing</category>

<body package="CADSM-UI" selector="defaultControllerClass">defaultControllerClass
	^OpenGLDisplayController</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	preferredBounds := Graphics.Rectangle origin: 0 @ 0 corner: 1 @ 1.
	cHandle := CADSM.Misc.CADSMMiscOrderedSet new.
	bitmapSemaphore := Semaphore forMutualExclusion</body>

<body package="CADSM-UI" selector="release">release
	super release.
	self flushCachedBitmap</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>rendering</category>

<body package="CADSM-UI" selector="renderingContext">renderingContext
	| renderingContext |
	renderingContext := aCamera aRenderingContextOn: self cachedBitmap.
	^renderingContext</body>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	aRenderingContext clear.
	cHandle do: [:aHandle | aHandle renderOn: aRenderingContext].
	self model renderOn: aRenderingContext</body>

<body package="CADSM-UI" selector="renderOn:withDisplayList:">renderOn: renderingContext withDisplayList: aDisplayListHolder 
	self model renderOn: renderingContext withDisplayList: aDisplayListHolder</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>updating</category>

<body package="CADSM-UI" selector="update:with:from:">update: aspectSymbol with: aParameter from: aSender 
	((self respondsTo: #isOpen)
		and: [self isOpen])
		ifTrue: 
			[aspectSymbol = #object ifTrue: [^self redisplay].
			aspectSymbol = #light ifTrue: [^self redisplay].
			aspectSymbol = #projection ifTrue: [^self displayOn: self graphicsContext].
			aspectSymbol = #presentation ifTrue: [^self redisplay].
			aspectSymbol = #shading ifTrue: [^self redisplay].
			aspectSymbol = #selection ifTrue: [^self redisplay].
			aspectSymbol = #state ifTrue: [^self controller flushMovementVector].
			aspectSymbol = #texture ifTrue: [^self redisplay]].
	super update: aspectSymbol with: aParameter</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>menubar items</category>

<body package="CADSM-UI" selector="menuViewYupQuadmpm">menuViewYupQuadmpm
	aCamera menuViewYupQuadmpm</body>

<body package="CADSM-UI" selector="menuViewYupXright">menuViewYupXright
	aCamera menuViewYupXright</body>

<body package="CADSM-UI" selector="menuViewZupQuadmmp">menuViewZupQuadmmp
	aCamera menuViewZupQuadmmp</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLView</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="calcBoundsAndRedisplay:">calcBoundsAndRedisplay: aUniverse 
	"aBoundingBoxPx is in OpenGL convention: origin is lower left corner, X right, Y up.
aBoundingRectPx is in VW convention: origin is upper left corner, X right, Y down."

	| aBoundingBoxPx yBoxRectBoxPx rRectOriginRectPx rRectCornerRectPx aBoundingRectPx |
	aBoundingBoxPx := self calcViewBoxFor: aUniverse aBoundingBox.
	yBoxRectBoxPx := self bounds extent y.
	rRectOriginRectPx := aBoundingBoxPx origin x 
				@ (yBoxRectBoxPx - aBoundingBoxPx origin y).
	rRectCornerRectPx := aBoundingBoxPx corner x 
				@ (yBoxRectBoxPx - aBoundingBoxPx corner y).
	aBoundingRectPx := Graphics.Rectangle vertex: rRectOriginRectPx
				vertex: rRectCornerRectPx.
	self preferredBounds quadrupleToContain: aBoundingRectPx.
"	self invalidate."
	self container scrollCADSM</body>

<body package="CADSM-UI" selector="displayOn:">displayOn: graphicsContext 
	bitmapSemaphore critical: 
			["self debugShow: graphicsContext clippingBounds."

			self asBitmap 
				displayOn: graphicsContext
				at: graphicsContext clippingBounds origin
				bounds: graphicsContext clippingBounds]</body>

<body package="CADSM-UI" selector="displaySelectionTrackingFrom:to:">displaySelectionTrackingFrom: arg1 to: arg2 
	| graphicsContext renderingContext array |
	graphicsContext := self graphicsContext.
	bitmapSemaphore critical: 
			[self 
				assert: [renderingContext := self renderingContext]
				do: 
					[self renderOn: renderingContext.
					renderingContext inScreenCoordDo: 
							[array := (Graphics.Rectangle origin: arg1 corner: arg2) asPointArray 
										collect: 
											[:aPoint | 
											StMFullColumn 
												with: aPoint x asDouble
												with: aPoint y asDouble
												with: 0.0d].
							renderingContext lineWidth: 1.
							renderingContext paint: ColorValue yellow.
							renderingContext displayLines: array].
					renderingContext flush]
				ensure: [renderingContext release].
			self cachedBitmap 
				displayOn: graphicsContext
				at: graphicsContext clippingBounds origin
				bounds: graphicsContext clippingBounds]</body>

<body package="CADSM-UI" selector="pick3dObjectAt:">pick3dObjectAt: rvGLpvGL 
	| pickingRenderingContext pickedObject |
	self 
		assert: 
			[pickingRenderingContext := OpenGLPickingRenderingContext 
						extent: self bounds extent]
		do: 
			[pickedObject := pickingRenderingContext 
						pickAt: rvGLpvGL
						aCamera: aCamera
						aModel: self model]
		ensure: [pickingRenderingContext release].
	^pickedObject</body>

<body package="CADSM-UI" selector="pickAt:">pickAt: rvGLpvGL 
	| pickedObject |
	pickedObject := self pickHandleAt: rvGLpvGL.
	pickedObject ifNil: [pickedObject := self pick3dObjectAt: rvGLpvGL].
	^pickedObject</body>

<body package="CADSM-UI" selector="pickHandleAt:">pickHandleAt: rvGLpvGL 
	| cH |
	cH := cHandle select: 
					[:aHandle | 
					| rvov rect |
					rvov := aHandle originPx.
					rect := (Graphics.Rectangle origin: rvov x @ rvov y corner: rvov x @ rvov y) 
								expandedBy: aHandle image extent // 2 + 1.
					rect containsPoint: rvGLpvGL].
	^cH isEmpty 
		ifTrue: [nil]
		ifFalse: 
			[cH := cH asSortedCollection: [:a :b | a originPx z &lt;= b originPx z].
			cH first]</body>

<body package="CADSM-UI" selector="redisplay">redisplay
	self flushCachedRenderingContext.
	self displayOn: self graphicsContext</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	self aGeoUniverse: CADSMGeoUniverse new.
	aTool := CADSMUISelectionTool new.
	aTool aMediator: self.
	cSelectedItem := CADSMUISelectionSet new.
	cMemento := Polymorphic.GFBoundedStack bound: 15.
	aTextCollector := TextCollector new.
	isDirty := false</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>GEO</category>

<body package="CADSM-UI" selector="deleteGEORootItem">deleteGEORootItem
	| geoRootItem |
	geoRootItem := self geoRootItem.
	geoRootItem == nil ifTrue: [^self].
	self noSelections.
	geoRootItem release.
	aGeoUniverse aAssembly: nil.
	aSketch := nil.
	self triggerEvent: #geoRootItemDeleted</body>

<body package="CADSM-UI" selector="noSelections">noSelections
	self hideHandles.
	cSelectedItem do: [:each | each deselect].
	cSelectedItem emptySelf.
	self triggerEvent: #deselect</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aEditor">aEditor
	^aEditor</body>

<body package="CADSM-UI" selector="aEditor:">aEditor: anObject
	aEditor := anObject</body>

<body package="CADSM-UI" selector="aFilename">aFilename
	^aFilename</body>

<body package="CADSM-UI" selector="aFilename:">aFilename: anObject
	aFilename := anObject</body>

<body package="CADSM-UI" selector="aGeoUniverse">aGeoUniverse
	^aGeoUniverse</body>

<body package="CADSM-UI" selector="aGeoUniverse:">aGeoUniverse: aUniverse 
	aUniverse removeSup.
	aUniverse aSup: self.
	aGeoUniverse := aUniverse</body>

<body package="CADSM-UI" selector="aMbDUniverse">aMbDUniverse
	^aMbDUniverse</body>

<body package="CADSM-UI" selector="aMbDUniverse:">aMbDUniverse: aUniverse 
	aUniverse removeSup.
	aUniverse aSup: self.
	aMbDUniverse := aUniverse</body>

<body package="CADSM-UI" selector="aMediator">aMediator
	^self</body>

<body package="CADSM-UI" selector="aTool">aTool
	^aTool</body>

<body package="CADSM-UI" selector="aTool:">aTool: anObject
	aTool := anObject</body>

<body package="CADSM-UI" selector="cSelectedItem">cSelectedItem
	^cSelectedItem</body>

<body package="CADSM-UI" selector="cSelectedItem:">cSelectedItem: anObject
	cSelectedItem := anObject</body>

<body package="CADSM-UI" selector="geoRootItem">geoRootItem
	^aGeoUniverse aAssembly</body>

<body package="CADSM-UI" selector="geoRootItem:">geoRootItem: aAssembly 
	aGeoUniverse aAssembly: aAssembly</body>

<body package="CADSM-UI" selector="isDirty:">isDirty: boolean 
	isDirty := boolean</body>

<body package="CADSM-UI" selector="selections">selections
	^cSelectedItem</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>menubar items</category>

<body package="CADSM-UI" selector="doTiltRotateUniverseInView:">doTiltRotateUniverseInView: aView 
	| aTiltUniverseHandle aRotateUniverseHandle |
	aView clearcHandle.
	aView fit: aGeoUniverse aBoundingBox.
	aTiltUniverseHandle := TiltUniverseHandle new.
	aTiltUniverseHandle aSpatialItem: aGeoUniverse.
	aView addHandle: aTiltUniverseHandle.
	aRotateUniverseHandle := RotateUniverseHandle new.
	aRotateUniverseHandle aSpatialItem: aGeoUniverse.
	aView addHandle: aRotateUniverseHandle.
	aView calcBoundsAndRedisplay: aGeoUniverse</body>

<body package="CADSM-UI" selector="doYupQuadmpmInView:">doYupQuadmpmInView: aView 
	aView clearcHandle.
	aView menuViewYupQuadmpm.
	aView calcBoundsAndRedisplay: aGeoUniverse</body>

<body package="CADSM-UI" selector="doYupXrightInView:">doYupXrightInView: aView 
	aView clearcHandle.
	aView menuViewYupXright.
	aView calcBoundsAndRedisplay: aGeoUniverse</body>

<body package="CADSM-UI" selector="doZoomIn">doZoomIn
	self aTool: ((CADSMUIZoomInTool new)
				name: 'Zoom In';
				aIcon: (CADSMUITool stockIconFor: 'Line');
				aCursor: Cursor crossHair;
				yourself)</body>

<body package="CADSM-UI" selector="doZupQuadmmpInView:">doZupQuadmmpInView: aView 
	aView clearcHandle.
	aView menuViewZupQuadmmp.
	aView calcBoundsAndRedisplay: aGeoUniverse</body>

<body package="CADSM-UI" selector="menuFileOpenAssembly">menuFileOpenAssembly
	| titleString filterArray aFilenameString newName prompt originalDir newDir readStream bos geoAssembly stack |
	(('win32*' match: OSHandle currentPlatformID) 
		or: ['unix*linux*' match: OSHandle currentPlatformID]) 
			ifTrue: 
				[titleString := 'Open an Assembly'.
				filterArray := OrderedCollection new.
				filterArray 
					add: (CommonFileFilter filter: '*.asm*' description: '*.asm*  (Assembly)').
				filterArray 
					add: (CommonFileFilter filter: '*.*' description: '*.*  (All)').
				aFilenameString := self aFilename.
				aFilenameString := aFilenameString isNil 
							ifTrue: ['']
							ifFalse: [aFilenameString asFilename tail].
				newName := CommonFileSelectionDialog 
							openTitle: titleString
							filters: filterArray
							filename: aFilenameString
							mustExist: true]
			ifFalse: 
				[prompt := 'Enter aFilename to read a Assembly.  Use wildcards (*.asm) to get list of relevant Assembly files.'.
				newName := self fileName.
				newName := newName isNil 
							ifTrue: [Dialog requestFileName: prompt default: '*.asm*']
							ifFalse: 
								[originalDir := Filename currentDirectory directory.
								newDir := newName asFilename directory.
								newDir beCurrentDirectory.
								[Dialog requestFileName: prompt default: '*.asm*'] 
									ensure: [originalDir beCurrentDirectory]]].
	(newName notNil and: [newName isEmpty not]) 
		ifTrue: 
			[self aFilename: newName.
			
			[readStream := newName asFilename readStream.
			
			[bos := BinaryObjectStorage onOldNoScan: readStream.
			geoAssembly := bos contents at: 1] 
					valueNowOrOnUnwindDo: [readStream close]] 
					on: Error
					do: [:ex | ex return].
			geoAssembly isNil 
				ifTrue: 
					[readStream := newName asFilename readStream.
					
					[stack := ASMTextParser parse: readStream contents cleanSourceFromSelf
								as: #asmt.
					geoAssembly := stack last] 
							valueNowOrOnUnwindDo: [readStream close]].
			(geoAssembly notNil and: [geoAssembly isAssembly]) 
				ifTrue: 
					[self deleteGEORootItem.
					self geoRootItem: geoAssembly.
					self changed: #object.
					self isDirty: false]
				ifFalse: [Dialog warn: 'Error reading an assembly from file.']]</body>

<body package="CADSM-UI" selector="menuViewPresentationHideLine">menuViewPresentationHideLine
	aGeoUniverse viewAsHideLine</body>

<body package="CADSM-UI" selector="menuViewPresentationSolid">menuViewPresentationSolid
	aGeoUniverse viewAsSolid</body>

<body package="CADSM-UI" selector="menuViewPresentationWireframe">menuViewPresentationWireframe
	aGeoUniverse viewAsWireframe</body>

<body package="CADSM-UI" selector="scrollView:by:">scrollView: aView by: aPoint 
	aView scrollCameraBy: aPoint.
	aView preferredBounds moveBy: aPoint.
	aView calcBoundsAndRedisplay: aGeoUniverse</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="hideHandles">hideHandles
	self notYetImplemented</body>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	aGeoUniverse renderOn: aRenderingContext</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>calc</category>

<body package="CADSM-UI" selector="calcBoundingBox">calcBoundingBox
	"Do nothing."</body>

<body package="CADSM-UI" selector="clearBoundingBox">clearBoundingBox
	"Do nothing."

	</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIMediator</class-id> <category>As yet unclassified</category>

<body package="CADSM-UI" selector="aMbDSolver">aMbDSolver
	^aMbDUniverse aMbDSolver</body>

<body package="CADSM-UI" selector="animateFrame:">animateFrame: integer 
	aGeoUniverse updateForFrame: integer.
	aGeoUniverse aRefFrame quietlyChanged.
	aEditor cadView redisplay</body>

<body package="CADSM-UI" selector="animationData">animationData
	^aGeoUniverse animationData</body>

<body package="CADSM-UI" selector="cadAnimateSeries:">cadAnimateSeries: series 
	series do: 
			[:i | 
			(aGeoUniverse canUpdateForFrame: i) 
				ifFalse: 
					[self halt.
					^false]].
	^true</body>

<body package="CADSM-UI" selector="cadApp">cadApp
	^aEditor</body>

<body package="CADSM-UI" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^aGeoUniverse canUpdateForFrame: integer</body>

<body package="CADSM-UI" selector="fullpath">fullpath
	^OrderedCollection with: self</body>

<body package="CADSM-UI" selector="geoAssembly">geoAssembly
	^aGeoUniverse activeAssembly</body>

<body package="CADSM-UI" selector="logString:">logString: string 
	aTextCollector logString: string</body>

<body package="CADSM-UI" selector="performSimulation:">performSimulation: symbol 
	| choices values initialState geoAssembly aSimulationData elapsedSeconds |
	choices := OrderedCollection new.
	values := OrderedCollection new.
	choices add: 'previous input state'.
	values add: [self updateFromInputState].
	choices add: 'initial assembled state'.
	values add: [self updateFromInitiallyAssembledState].
	choices add: 'current state'.
	values add: [].
	initialState := Dialog 
				choose: 'Which input state do you want \to use for the current simulation?' 
						withCRs
				fromList: choices
				values: values
				lines: 4
				cancel: nil.
	initialState notNil 
		ifTrue: 
			[geoAssembly := self geoAssembly.
			aSimulationData := geoAssembly aSimulationData 
						ifNil: [CADSMDataSimulation new]
						ifNotNil: [:simData | simData copy].
			(StCAD.CADSimulationDialog openOn: aSimulationData) 
				ifTrue: 
					[initialState value.
					geoAssembly
						storeInputState;
						aSimulationData: aSimulationData.
					aProcess := 
							[self aMbDUniverse: CADSM.MbD.CADSMMbDUniverse new.
							aGeoUniverse mbdObject: aMbDUniverse.
							self logString: #'ADM \\\Starting Simulation.'.
							elapsedSeconds := Time secondsToRun: 
											[[aMbDUniverse perform: symbol] on: SimulationStoppingError
												do: [:ex | ex return]].
							self logString: #'ADM \Elapsed time is %1 seconds.'
								withArgument: elapsedSeconds printString.
							self aMbDUniverse: nil] 
									forkAt: Processor userBackgroundPriority]]</body>

<body package="CADSM-UI" selector="preMbDrun">preMbDrun
	aGeoUniverse preMbDrun</body>

<body package="CADSM-UI" selector="startDynamic">startDynamic
	self performSimulation: #runDYNAMIC</body>

<body package="CADSM-UI" selector="timeSeries">timeSeries
	^aGeoUniverse timeSeries</body>

<body package="CADSM-UI" selector="unhideHandles">unhideHandles
	self notYetImplemented</body>

<body package="CADSM-UI" selector="updateForFrame:">updateForFrame: integer 
	aGeoUniverse updateForFrame: integer.
	aGeoUniverse aRefFrame calcAll</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIAlibreDesign class</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aIADTransformationArray_rFfF:aAFf:">aIADTransformationArray_rFfF: rFfF aAFf: aAFf 
	"Returns array of 16 elements in column order."

	| aStream |
	aStream := (Array new: 16) writeStream.
	1 to: 3
		do: 
			[:i | 
			aStream nextPutAll: (aAFf column: i).
			aStream nextPut: 0.0d].
	aStream nextPutAll: rFfF.
	aStream nextPut: 1.0d.
	^aStream contents</body>

<body package="CADSM-UI" selector="rFfF_aAFf_IADTransformationArray:">rFfF_aAFf_IADTransformationArray: aArray 
	"Returns array of rFfF and aAFf."

	| rFfF aAFf aAFfi |
	rFfF := StCAD.StMath.StMFullColumn new: 3.
	aAFf := StCAD.StMath.StMFullMatrix new: 3 by: 3.
	1 to: 3
		do: 
			[:i | 
			rFfF at: i put: (aArray at: i + 12) asDouble.
			aAFfi := aAFf at: i.
			1 to: 3 do: [:j | aAFfi at: j put: (aArray at: i + (4 * (j - 1))) asDouble]].
	^Array with: rFfF with: aAFf</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIZoomInTool</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aCursor">aCursor
	^aCursor</body>

<body package="CADSM-UI" selector="aCursor:">aCursor: anObject
	aCursor := anObject</body>

<body package="CADSM-UI" selector="aIcon">aIcon
	^aIcon</body>

<body package="CADSM-UI" selector="aIcon:">aIcon: anObject
	aIcon := anObject</body>

<body package="CADSM-UI" selector="name">name
	^name</body>

<body package="CADSM-UI" selector="name:">name: anObject
	name := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIOpenGLImage</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aImage">aImage
	aImage isNil 
		ifTrue: 
			[| palette value |
			palette := FixedPalette 
						redShift: 16
						redMask: 255
						greenShift: 8
						greenMask: 255
						blueShift: 0
						blueMask: 255.
			aImage := Image 
						extent: 1 @ 1
						depth: 24
						palette: palette.
			value := aImage palette indexOfPaintNearest: ColorValue black.
			aImage atPoint: 0 @ 0 put: value].
	^aImage</body>

<body package="CADSM-UI" selector="aImage:">aImage: image 
	(image width = 0 or: [image height = 0]) ifTrue: [^self].
	aImage := image.
	self flushCPointer</body>

<body package="CADSM-UI" selector="height">height
	^self aImage height</body>

<body package="CADSM-UI" selector="width">width
	^self aImage width</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIOpenGLImage</class-id> <category>externals</category>

<body package="CADSM-UI" selector="flushCPointer">flushCPointer
	aCPointer notNil ifTrue: [aCPointer free].
	aCPointer := nil</body>

<body package="CADSM-UI" selector="pointerOfPixels">pointerOfPixels
	aCPointer isNil 
		ifTrue: 
			[Cursor execute showWhile: 
					[| aImageWidth aImageHeight byteArray index |
					aImageWidth := self aImage width.
					aImageHeight := self aImage height.
					byteArray := ByteArray new: aImageWidth * aImageHeight * 3.
					index := 0.
					aImageHeight - 1 to: 0
						by: -1
						do: 
							[:y | 
							| color red green blue |
							0 to: aImageWidth - 1
								do: 
									[:x | 
									color := self aImage valueAtPoint: x @ y.
									red := 0 max: ((color red * 255) asInteger min: 255).
									green := 0 max: ((color green * 255) asInteger min: 255).
									blue := 0 max: ((color blue * 255) asInteger min: 255).
									index := index + 1.
									byteArray at: index put: red.
									index := index + 1.
									byteArray at: index put: green.
									index := index + 1.
									byteArray at: index put: blue]].
					aCPointer := JunForeignHeap copyByteArrayToGcHeap: byteArray]].
	^aCPointer</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUIOpenGLImage class</class-id> <category>instance creation</category>

<body package="CADSM-UI" selector="aImage:">aImage: image 
	^(self new)
		aImage: image;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.UI.RotateTracker</class-id> <category>private</category>

<body package="CADSM-UI" selector="doSelectionTrackingOperationAt:">doSelectionTrackingOperationAt: rvNewv 
	| radialVector |
	radialVector := 100 @ 0 + (controller aOpenGLPointFor: rvNewv) - rvFirstv.
	radialVector isZero 
		ifFalse: 
			[| aView rCrotateC aCameraFrame aAOC aAFC rFrotateF thetaF newFrame |
			aView := aHandle aView.
			rCrotateC := frozenFrame unitz.
			aCameraFrame := aView aCamera aRefFrame.
			aAOC := aFrame == aCameraFrame 
						ifTrue: [frozenFrame aAOf]
						ifFalse: [aCameraFrame aAOf].
			aAFC := frozenFrame aAOF transpose timesFullMatrix: aAOC.
			rFrotateF := aAFC timesFullColumn: rCrotateC.
			thetaF := radialVector theta asDouble.
			newFrame := frozenFrame copy.
			newFrame 
				rotateAt_rFpvF: rFcenterF
				axisF: rFrotateF
				theta: thetaF * direction.
			aFrame copyrFfFandAFfFrom: newFrame.
			aView calcBoundsAndRedisplay: aHandle aSpatialItem]</body>
</methods>

<methods>
<class-id>CADSM.UI.Handle</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	self subclassResponsibility</body>
</methods>

<methods>
<class-id>CADSM.UI.Handle</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aView">aView
	^aView</body>

<body package="CADSM-UI" selector="aView:">aView: anObject
	aView := anObject</body>

<body package="CADSM-UI" selector="image">image
	^image ifNil: [image := self class handleImage]</body>

<body package="CADSM-UI" selector="originPx">originPx
	^originPx</body>

<body package="CADSM-UI" selector="originPx:">originPx: anObject
	originPx := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.UniverseHandle</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aSpatialItem">aSpatialItem
	^aSpatialItem</body>

<body package="CADSM-UI" selector="aSpatialItem:">aSpatialItem: anObject
	aSpatialItem := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.RotateUniverseHandle</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	aRenderingContext displayRotateHandle: self</body>
</methods>

<methods>
<class-id>CADSM.UI.RotateUniverseHandle</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="selectionTracker">selectionTracker
	| rOcenterO aCameraFrame rFcenterF |
	rOcenterO := aSpatialItem aRefFrame 
				rOpOfromrfpf: aSpatialItem aBoundingBox center.
	aCameraFrame := aView aCamera aRefFrame.
	rFcenterF := aCameraFrame rFpFfromrOpO: rOcenterO.
	^(RotateTracker new)
		setController: aView controller;
		aHandle: self;
		aFrame: aCameraFrame;
		rFcenterF: rFcenterF;
		direction: -1;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.UI.TiltHandle</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	self halt</body>
</methods>

<methods>
<class-id>CADSM.UI.TiltUniverseHandle</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="selectionTracker">selectionTracker
	| rOcenterO aCameraFrame rFcenterF |
	rOcenterO := aSpatialItem aRefFrame 
				rOpOfromrfpf: aSpatialItem aBoundingBox center.
	aCameraFrame := aView aCamera aRefFrame.
	rFcenterF := aCameraFrame rFpFfromrOpO: rOcenterO.
	^(TiltTracker new)
		setController: aView controller;
		aHandle: self;
		aFrame: aCameraFrame;
		rFcenterF: rFcenterF;
		direction: -1;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.UI.TiltUniverseHandle</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="renderOn:">renderOn: aRenderingContext 
	aRenderingContext displayTiltHandle: self</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMtoCOM</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	self aRefFrame: ((StCAD.StGeo.GEOWorldFrame2 new)
				refFrame: self;
				fixedAtRef;
				yourself).
	aTextCollector := TextCollector new.
	pauseAfterOutput := false.
	criticalSectionSemaphore := Semaphore forMutualExclusion</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMtoCOM</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="aAssembly">aAssembly
	^aAssembly</body>

<body package="CADSM-UI" selector="aAssembly:">aAssembly: aaAssembly 
	"aSub maybe already in a tree. Make sure aSub is released by its aSup."

	aaAssembly removeSup.
	self addRefFrame: aaAssembly aRefFrame.
	aAssembly := aaAssembly.
	aaAssembly aSup: self.
	^aaAssembly</body>

<body package="CADSM-UI" selector="aCADSMAlibre">aCADSMAlibre
	^aCADSMAlibre</body>

<body package="CADSM-UI" selector="aCADSMAlibre:">aCADSMAlibre: anObject
	aCADSMAlibre := anObject</body>

<body package="CADSM-UI" selector="addRefFrame:">addRefFrame: argRefFrame 
	"Example usage:

	addSurface: aSurface 
		aSurface removeSup.
		super addRefFrame: aSurface aRefFrame.
		cSurface add: aSurface.
		aSurface aSup: self.
		^aSurface
	"

	self aRefFrame addSub: argRefFrame</body>

<body package="CADSM-UI" selector="aMbDSystem">aMbDSystem
	^aMbDSystem</body>

<body package="CADSM-UI" selector="aMbDSystem:">aMbDSystem: aaMbDSystem 
	aMbDSystem := aaMbDSystem.
	aaMbDSystem ifNotNil: [aaMbDSystem admSystem: self]</body>

<body package="CADSM-UI" selector="aRefFrame">aRefFrame
	^aWorldFrame</body>

<body package="CADSM-UI" selector="aRefFrame:">aRefFrame: aaRefFrame 
	aWorldFrame := aaRefFrame.
	aaRefFrame body: self</body>

<body package="CADSM-UI" selector="connectorList">connectorList
	| collection |
	collection := SortedCollection sortBlock: [:a :b | a name &lt;= b name].
	aAssembly == nil ifFalse: [aAssembly connectorList: collection].
	^collection</body>

<body package="CADSM-UI" selector="fullpath">fullpath
	^OrderedCollection with: self</body>

<body package="CADSM-UI" selector="getString:">getString: string 
	^aTextCollector getString: string</body>

<body package="CADSM-UI" selector="interface">interface
	^self</body>

<body package="CADSM-UI" selector="isInterface">isInterface
	^true</body>

<body package="CADSM-UI" selector="mbdSystem">mbdSystem
	^aMbDSystem</body>

<body package="CADSM-UI" selector="mbdUnits">mbdUnits
	^mbdUnits</body>

<body package="CADSM-UI" selector="mbdUnits:">mbdUnits: anObject
	mbdUnits := anObject</body>

<body package="CADSM-UI" selector="messages">messages
	| answer |
	answer := (IOAccessor 
				convertStringForPlatform: aTextCollector value string) asString.
	aTextCollector clear.
	^answer</body>

<body package="CADSM-UI" selector="nFrames">nFrames
	^aAssembly dataSeries size</body>

<body package="CADSM-UI" selector="partList">partList
	| collection |
	collection := SortedCollection sortBlock: [:a :b | a name &lt;= b name].
	aAssembly == nil ifFalse: [aAssembly partList: collection].
	^collection</body>

<body package="CADSM-UI" selector="pauseAfterOutput">pauseAfterOutput
	^pauseAfterOutput</body>

<body package="CADSM-UI" selector="pauseAfterOutput:">pauseAfterOutput: anObject
	pauseAfterOutput := anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMtoCOM</class-id> <category>DYN</category>

<body package="CADSM-UI" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^aAssembly canUpdateForFrame: integer</body>

<body package="CADSM-UI" selector="isSimulating">isSimulating
	| answer |
	answer := (mbdProcess isMemberOf: Process) 
				and: [mbdProcess isTerminated not].
	^answer</body>

<body package="CADSM-UI" selector="outputFor:">outputFor: analysisType 
	"Yield process at the end of output so that current process may be aborted safely."

	((analysisType == #DYNAMIC or: [analysisType == #'INITIAL CONDITIONS']) 
		or: [analysisType == #STATIC]) 
			ifTrue: 
				[aAssembly updateFromMbD.
				aAssembly refFrame changed.
				self tellAlibreOfFrame: aAssembly dataSeries size]
			ifFalse: 
				[analysisType == #INPUT 
					ifTrue: 
						[aAssembly storeInputFromMbD.
						self tellAlibreOfFrame: 0]
					ifFalse: 
						[analysisType == #DISCONTINUITY 
							ifTrue: [aAssembly storeDiscontinuityFromMbD]]].
	Processor yield</body>

<body package="CADSM-UI" selector="performSimulation:">performSimulation: symbol 
	self isSimulating 
		ifTrue: 
			[self 
				error: 'A simulation is running. &lt;n&gt;Stop current simulation before starting a new one.' 
						expandMacros]
		ifFalse: 
			[aAssembly storeInputState.
			self outputDebug1ASM.
			self deleteDebugTxt.
			mbdProcess := 
					[| elapsedSeconds |
					aMbDSystem := MbDSystem new.
					self aMbDSystem: aMbDSystem.
					self logString: #'ADM \\\Starting Simulation.'.
					elapsedSeconds := Time secondsToRun: 
									[[aMbDSystem perform: symbol] on: SimulationStoppingError
										do: [:ex | ex return]].
					self logString: #'ADM \Elapsed time is %1 seconds.'
						withArgument: elapsedSeconds printString.
					self aMbDSystem: nil.
					aCADSMAlibre ifNotNil: [aCADSMAlibre simulationComplete].
					self outputDebug2ASM] 
							forkAt: Processor userBackgroundPriority]</body>

<body package="CADSM-UI" selector="postMbDrun">postMbDrun
	aAssembly deleteMbD</body>

<body package="CADSM-UI" selector="preMbDrun">preMbDrun
	aAssembly calcCharacteristicDimensions.
	aAssembly deleteMbD.
	aAssembly createMbD.
	aAssembly mbdObject asFixed</body>

<body package="CADSM-UI" selector="resumeSimulation">resumeSimulation
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[[mbdProcess resume] on: Error do: [:ex | ex return].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="resumeSimulation1">resumeSimulation1
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[
			[self toTranscriptShow: 'resume1'.
			mbdProcess resume.
			self toTranscriptShow: 'resume2'] 
					on: Error
					do: 
						[:ex | 
						self toTranscriptShow: 'resume error'.
						ex return].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="resumeSimulation2">resumeSimulation2
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[[mbdProcess proceed] on: Error do: [:ex | ex pass	"return"].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="resumeSimulation3">resumeSimulation3
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	| sem |
	self isSimulating 
		ifTrue: 
			[sem := Semaphore new.
			
			[
			[self toTranscriptShow: 'resume1'.
			mbdProcess resume.
			self toTranscriptShow: 'resume2'] 
					on: Error
					do: 
						[:ex | 
						self toTranscriptShow: 'resume error'.
						self toTranscriptShow: 'resume1'.
						mbdProcess resume.
						self toTranscriptShow: 'resume2'.
						ex return].
			sem signal] 
					valueUnpreemptively.
			sem wait.
			Cursor normal show]</body>

<body package="CADSM-UI" selector="resumeSimulation4">resumeSimulation4
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[criticalSectionSemaphore critical: 
					[self toTranscriptShow: 'resume1'.
					mbdProcess resume.
					self toTranscriptShow: 'resume2'].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="resumeSimulation5">resumeSimulation5
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[[mbdProcess resume] on: Error do: [:ex | ex return].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="startDynamic">startDynamic
	self performSimulation: #runDYNAMIC</body>

<body package="CADSM-UI" selector="startKinematic">startKinematic
	self performSimulation: #runKINEMATIC</body>

<body package="CADSM-UI" selector="startQuasiStatic">startQuasiStatic
	"
	Convergence is fragile for quasistatic analysis.
	When there is no convergence, the aA matrices are no longer valid rotation matrices. So all geometry is no longer correct. Condition the aA matrices to avoid the problem.
	"

	self performSimulation: #runSTATICS.
	(aAssembly refFrame)
		conditionA;
		changed</body>

<body package="CADSM-UI" selector="startTransient">startTransient
	self performSimulation: #runTRANSIENT</body>

<body package="CADSM-UI" selector="stopSimulation">stopSimulation
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	| sem |
	self isSimulating 
		ifTrue: 
			[sem := Semaphore new.
			
			[mbdProcess terminate.
			mbdProcess := nil.
			sem signal] 
					forkAt: mbdProcess priority.
			sem wait.
			Cursor normal show]</body>

<body package="CADSM-UI" selector="suspendSimulation">suspendSimulation
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[[[mbdProcess suspend] on: Error do: [:ex | ex return]] 
				forkAt: Processor activeProcess priority.
			Cursor normal show]</body>

<body package="CADSM-UI" selector="suspendSimulation1">suspendSimulation1
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[
			[self toTranscriptShow: 'suspend1'.
			mbdProcess suspend.
			self toTranscriptShow: 'suspend2'] 
					on: Error
					do: 
						[:ex | 
						self toTranscriptShow: 'suspend error'.
						ex return].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="suspendSimulation2">suspendSimulation2
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[
			[
			[self toTranscriptShow: 'suspend1'.
			mbdProcess suspend.
			self toTranscriptShow: 'suspend2'] 
					on: Error
					do: 
						[:ex | 
						self toTranscriptShow: 'suspend error'.
						ex return]] 
					forkAt: Processor activeProcess priority.
			self toTranscriptShow: 'suspend3'.
			Cursor normal show]</body>

<body package="CADSM-UI" selector="suspendSimulation3">suspendSimulation3
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	| sem |
	self isSimulating 
		ifTrue: 
			[sem := Semaphore new.
			self toTranscriptShow: (Array with: 'suspendSimulation'
						with: Processor activeProcess priority).
			
			[
			[self toTranscriptShow: 'suspend1'.
			mbdProcess suspend.
			self toTranscriptShow: 'suspend2'] 
					on: Error
					do: 
						[:ex | 
						self toTranscriptShow: 'suspend error'.
						self toTranscriptShow: 'suspend1'.
						mbdProcess suspend.
						self toTranscriptShow: 'suspend2'.
						ex return].
			sem signal] 
					forkAt: Processor activeProcess priority + 1.
			sem wait.
			Cursor normal show]</body>

<body package="CADSM-UI" selector="suspendSimulation4">suspendSimulation4
	"
	The garbage can cursor persists when this command is executed during garbage collection.
	'Cursor normal show' forces a normal cursor.
	"

	self isSimulating 
		ifTrue: 
			[criticalSectionSemaphore critical: 
					[self toTranscriptShow: 'suspend1'.
					mbdProcess suspend.
					self toTranscriptShow: 'suspend2'].
			Cursor normal show]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame1:">tellAlibreOfFrame1: i 
	aCADSMAlibre ifNotNil: 
			[aCADSMAlibre newFrame: i.
			pauseAfterOutput ifTrue: [self suspendSimulation]]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame2:">tellAlibreOfFrame2: i 
	aCADSMAlibre ifNotNil: 
			[pauseAfterOutput ifTrue: [self suspendSimulation].
			aCADSMAlibre newFrame: i]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame3:">tellAlibreOfFrame3: i 
	aCADSMAlibre ifNotNil: 
			[
			[criticalSectionSemaphore critical: 
					[self toTranscriptShow: (Array with: 'tellAlibre1' with: i).
					aCADSMAlibre newFrame: i]] 
					forkAt: Processor activeProcess priority - 1.
			pauseAfterOutput 
				ifTrue: 
					[criticalSectionSemaphore critical: 
							[self toTranscriptShow: (Array with: 'tellAlibre2' with: i).
							self suspendSimulation]]]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame4:">tellAlibreOfFrame4: i 
	aCADSMAlibre ifNotNil: 
			[
			[self toTranscriptShow: (Array with: 'tellAlibre1' with: i).
			aCADSMAlibre newFrame: i] 
					forkAt: Processor activeProcess priority - 1.
			pauseAfterOutput 
				ifTrue: 
					[self toTranscriptShow: (Array with: 'tellAlibre2' with: i).
					self suspendSimulation]]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame5:">tellAlibreOfFrame5: i 
	aCADSMAlibre ifNotNil: 
			[pauseAfterOutput 
				ifTrue: 
					[
					[self toTranscriptShow: (Array with: 'tellAlibre1' with: i).
					aCADSMAlibre newFrame: i] 
							forkAt: Processor activeProcess priority - 1.
					self toTranscriptShow: (Array with: 'tellAlibre2' with: i).
					self suspendSimulation]
				ifFalse: 
					[self toTranscriptShow: (Array with: 'tellAlibre1' with: i).
					aCADSMAlibre newFrame: i]]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame6:">tellAlibreOfFrame6: i 
	aCADSMAlibre ifNotNil: 
			[pauseAfterOutput 
				ifTrue: 
					[[aCADSMAlibre newFrame: i] forkAt: Processor activeProcess priority - 1.
					self suspendSimulation]
				ifFalse: [aCADSMAlibre newFrame: i]]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame7:">tellAlibreOfFrame7: i 
	aCADSMAlibre ifNotNil: 
			[pauseAfterOutput 
				ifTrue: 
					[[aCADSMAlibre newFrame: i] forkAt: Processor activeProcess priority - 1.
					self suspendSimulation]
				ifFalse: [aCADSMAlibre newFrame: i]]</body>

<body package="CADSM-UI" selector="tellAlibreOfFrame:">tellAlibreOfFrame: i 
	aCADSMAlibre ifNotNil: 
			[pauseAfterOutput 
				ifTrue: 
					[
					[mbdProcess processState ~~ #suspend 
						ifTrue: [(Delay forMilliseconds: 100) wait].
					aCADSMAlibre newFrame: i] 
							forkAt: Processor activePriority - 1.
					self suspendSimulation]
				ifFalse: [aCADSMAlibre newFrame: i]]</body>

<body package="CADSM-UI" selector="useCollisionTrialStepStats:">useCollisionTrialStepStats: stats 
	| mbdUnits impulse array |
	mbdUnits := self mbdUnits.
	impulse := mbdUnits force * mbdUnits time.
	array := Array new: 6.
	array at: 1 put: (stats at: #istep) printString.
	array at: 2 put: ((stats at: #t) * impulse) asFloat printString.
	array at: 3 put: (stats at: #order) printString.
	array at: 4 put: ((stats at: #h) * impulse) asFloat printString.
	array at: 5 put: (stats at: #corIterNo) printString.
	array at: 6 put: (stats at: #truncError) asFloat printString.
	self logString: #'ADM: \%1 , imp=%2 , o=%3 , dimp=%4 , it=%5 , e=%6'
		withArguments: array</body>

<body package="CADSM-UI" selector="useDynTrialStepStats:">useDynTrialStepStats: stats 
	| time array |
	time := mbdUnits time.
	array := Array new: 6.
	array at: 1 put: (stats at: #istep) printString.
	array at: 2 put: ((stats at: #t) * time) asFloat printString.
	array at: 3 put: (stats at: #order) printString.
	array at: 4 put: ((stats at: #h) * time) asFloat printString.
	array at: 5 put: (stats at: #corIterNo) printString.
	array at: 6
		put: ((stats at: #truncError) ifNotNil: [:a | a asFloat]) printString.
	self logString: #'ADM: \%1 , t=%2 , o=%3 , h=%4 , it=%5 , e=%6'
		withArguments: array</body>

<body package="CADSM-UI" selector="useKineTrialStepStats:">useKineTrialStepStats: stats 
	self useDynTrialStepStats: stats</body>

<body package="CADSM-UI" selector="zeroAllVelocities">zeroAllVelocities
	self partList do: [:part | part zeroVelocities]</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMtoCOM</class-id> <category>output</category>

<body package="CADSM-UI" selector="logContactForce:">logContactForce: double 
	self logString: #'ADM: \Contact force = %1'
		withArgument: (double * self mbdUnits force) asFloat printString</body>

<body package="CADSM-UI" selector="logImpactVelocity:">logImpactVelocity: double 
	self logString: #'ADM: \Impact velocity = %1' withArgument: (double * self mbdUnits velocity) asFloat printString</body>

<body package="CADSM-UI" selector="logSeparationDistance:">logSeparationDistance: double 
	self logString: #'ADM: \Curve-curve separation = %1' withArgument: (double * self mbdUnits length) asFloat printString</body>

<body package="CADSM-UI" selector="logString:">logString: aString 
	self toDebugTxtShowString: aString mbdMessage.
	aTextCollector logString: aString</body>

<body package="CADSM-UI" selector="logString:withArgument:">logString: string withArgument: string1 
	self toDebugTxtShowString: (string mbdMessage expandWithArgument: string1).
	aTextCollector logString: string withArgument: string1</body>

<body package="CADSM-UI" selector="logString:withArguments:">logString: string withArguments: arrayOfStrings 
	self toDebugTxtShowString: (string mbdMessage 
				expandWithArguments: arrayOfStrings).
	aTextCollector logString: string withArguments: arrayOfStrings</body>

<body package="CADSM-UI" selector="outputASMFile:">outputASMFile: aFilename 
	| bos |
	bos := StCAD.BinaryObjectStorage onNew: aFilename asFilename writeStream.
	
	[aAssembly cadObject release.
	aAssembly preSave.
	aAssembly container: nil.
	aAssembly refFrame refFrame removeDependentFrame: aAssembly refFrame.
	aAssembly refFrame refFrame: nil.
	bos nextPut: aAssembly] 
			valueNowOrOnUnwindDo: [bos close].
	self aAssembly: aAssembly</body>

<body package="CADSM-UI" selector="outputDebug1ASM">outputDebug1ASM
	self outputASMFile: Filename findDefaultDirectory asString , '\debug1.asm'</body>

<body package="CADSM-UI" selector="outputDebug2ASM">outputDebug2ASM
"	self outputASMFile: Filename findDefaultDirectory asString , '\debug2.asm'"</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="displayImage:rOpO:">displayImage: aOpenGLImage rOpO: rOpO 
	self activate: 
			[OpenGLInterface glPixelStorei: OpenGLInterface GL_UNPACK_ALIGNMENT with: 1.
			OpenGLInterface 
				glRasterPos3d: rOpO x
				with: rOpO y
				with: rOpO z.
			OpenGLInterface 
				glDrawPixels: aOpenGLImage width
				with: aOpenGLImage height
				with: OpenGLInterface GL_RGB
				with: OpenGLInterface GL_UNSIGNED_BYTE
				with: aOpenGLImage pointerOfPixels]</body>

<body package="CADSM-UI" selector="displayImage:rOpO:rpqv:">displayImage: aOpenGLImage rOpO: rOpO rpqv: rpqv 
	"
	rOpO =  r from O to p in O components.
	rpqv = r from p to q (image lower left corner) in viewport components.
	"

	| rOqO |
	rOqO := self rOqOFromrOpO: rOpO rpqv: rpqv.
	self displayImage: aOpenGLImage rOpO: rOqO</body>

<body package="CADSM-UI" selector="displayLineFromrOpO:rpqv:">displayLineFromrOpO: rOpO rpqv: rpqv 
	"
	"

	| rOqO |
	self lineWidth: 1.
	self paint: ColorValue yellow.
	rOqO := self rOqOFromrOpO: rOpO rpqv: rpqv.
	self displayLine: (Array with: rOpO with: rOqO)</body>

<body package="CADSM-UI" selector="displayNurbsCurve:">displayNurbsCurve: aNurbsCurve 
	| aNurbs knotVector controlPoints weights floatArray |
	knotVector := aNurbsCurve knotVector collect: [:each | each asFloat].
	controlPoints := aNurbsCurve controlPoints.
	weights := aNurbsCurve weights.
	floatArray := WriteStream on: Array new.
	controlPoints with: weights
		do: 
			[:point :weight | 
			floatArray nextPut: (point x * weight) asFloat.
			floatArray nextPut: (point y * weight) asFloat.
			floatArray nextPut: (point z * weight) asFloat.
			floatArray nextPut: weight asFloat].
	floatArray := floatArray contents.
	self activate: 
			[self _enable: #GL_AUTO_NORMAL.
			aNurbs := OpenGLInterface gluNewNurbsRenderer.
			OpenGLInterface 
				gluNurbsProperty: aNurbs
				with: OpenGLInterface GLU_SAMPLING_TOLERANCE
				with: nurbsSamplingTolerance.
			OpenGLInterface glPushMatrix.
			OpenGLInterface gluBeginCurve: aNurbs.
			OpenGLInterface 
				gluNurbsCurve: aNurbs
				with: knotVector size
				with: (JunForeignHeap copyFloatArrayToGcHeap: knotVector)
				with: 4
				with: (JunForeignHeap copyFloatArrayToGcHeap: floatArray)
				with: aNurbsCurve order
				with: OpenGLInterface GL_MAP1_VERTEX_4.
			OpenGLInterface gluEndCurve: aNurbs.
			OpenGLInterface glPopMatrix.
			OpenGLInterface gluDeleteNurbsRenderer: aNurbs]</body>

<body package="CADSM-UI" selector="displayNurbsSurface:">displayNurbsSurface: aNurbsSurface 
	| savedPaint |
	self presentation = #wireframe 
		ifTrue: 
			[self displayNurbsSurface: aNurbsSurface
				displayMode: OpenGLInterface GLU_OUTLINE_POLYGON.
			^self].
	self presentation = #hiddenline 
		ifTrue: 
			[self disableLighting.
			savedPaint := nil.
			self paint = ColorValue white 
				ifTrue: 
					[savedPaint := self paint.
					self paint: (ColorValue brightness: 0.95)].
			OpenGLInterface glEnable: OpenGLInterface GL_DEPTH_TEST.
			OpenGLInterface glPolygonMode: OpenGLInterface GL_FRONT_AND_BACK
				with: OpenGLInterface GL_LINE.
			self displayNurbsSurface: aNurbsSurface
				displayMode: OpenGLInterface GLU_OUTLINE_POLYGON.
			savedPaint isNil ifFalse: [self paint: savedPaint].
			savedPaint := self paint.
			self paint: ColorValue white.
			OpenGLInterface glPolygonMode: OpenGLInterface GL_FRONT_AND_BACK
				with: OpenGLInterface GL_FILL.
			OpenGLInterface glEnable: OpenGLInterface GL_POLYGON_OFFSET_FILL.
			OpenGLInterface glPolygonOffset: 1.0 with: 1.0.
			self displayNurbsSurface: aNurbsSurface
				displayMode: OpenGLInterface GLU_FILL.
			OpenGLInterface glDisable: OpenGLInterface GL_POLYGON_OFFSET_FILL.
			self paint: savedPaint.
			self enableLighting.
			^self].
	^self displayNurbsSurface: aNurbsSurface
		displayMode: OpenGLInterface GLU_FILL</body>

<body package="CADSM-UI" selector="displayRotateHandle1:">displayRotateHandle1: aRotateHandle 
	| aOpenGLImage rOpO rvpv xOffset rpqv |
	aOpenGLImage := CADSMUIOpenGLImage aImage: aRotateHandle image.
	rOpO := aRotateHandle aSpatialItem aBoundingBox center.
	rvpv := self rvpvFromrOpO: rOpO.
	xOffset := 100.0d.
	rvpv at: 1 plusNumber: xOffset.
	aRotateHandle originPx: rvpv.
	rpqv := StMFullColumn 
				with: (aOpenGLImage width // 2 + 1) negated asDouble + xOffset
				with: (aOpenGLImage height // 2) negated asDouble
				with: 0.0d.
	self 
		displayImage: aOpenGLImage
		rOpO: rOpO
		rpqv: rpqv.
	rpqv := StMFullColumn 
				with: xOffset
				with: 0.0d
				with: 0.0d.
	self displayLineFromrOpO: rOpO rpqv: rpqv</body>

<body package="CADSM-UI" selector="displayRotateHandle:">displayRotateHandle: aRotateHandle 
	"Add 0.01d to remove rounding jitter."

	| aOpenGLImage rOpO rvpv xOffset rpqv rqsv |
	aOpenGLImage := CADSMUIOpenGLImage aImage: aRotateHandle image.
	rOpO := aRotateHandle aSpatialItem aBoundingBox center.
	rvpv := (self rvpvFromrOpO: rOpO) plusNumber: 0.01d.
	xOffset := 100.0d.
	rpqv := StMFullColumn 
				with: xOffset
				with: 0.0d
				with: 0.0d.
	aRotateHandle originPx: rvpv + rpqv.
	rqsv := StMFullColumn 
				with: (aOpenGLImage width // 2 + 1) negated asDouble
				with: (aOpenGLImage height // 2) negated asDouble
				with: 0.0d.
	self inScreenCoordDo: 
			[self displayImage: aOpenGLImage rOpO: rvpv + rpqv + rqsv.
			self lineWidth: 1.
			self paint: ColorValue yellow.
			self displayLine: (Array with: rvpv with: rvpv + rpqv)]</body>

<body package="CADSM-UI" selector="displayTiltHandle1:">displayTiltHandle1: aTiltHandle 
	| aOpenGLImage rOpO rpqv |
	aOpenGLImage := CADSMUIOpenGLImage aImage: aTiltHandle image.
	rOpO := aTiltHandle aSpatialItem aBoundingBox center.
	aTiltHandle originPx: (self rvpvFromrOpO: rOpO).
	rpqv := StMFullColumn 
				with: (aOpenGLImage width // 2 + 1) negated asDouble
				with: (aOpenGLImage height // 2) negated asDouble
				with: 0.0d.
	self 
		displayImage: aOpenGLImage
		rOpO: rOpO
		rpqv: rpqv</body>

<body package="CADSM-UI" selector="displayTiltHandle2:">displayTiltHandle2: aTiltHandle 
	"Add 0.01d to remove rounding jitter."

	| aOpenGLImage rOpO rpqv rvpv |
	aOpenGLImage := CADSMUIOpenGLImage aImage: aTiltHandle image.
	rOpO := aTiltHandle aSpatialItem aBoundingBox center.
	rvpv := (self rvpvFromrOpO: rOpO) plusNumber: 0.01d.
	aTiltHandle originPx: rvpv.
	rpqv := StMFullColumn 
				with: (aOpenGLImage width // 2 + 1) negated asDouble
				with: (aOpenGLImage height // 2) negated asDouble
				with: 0.0d.
	self inScreenCoordDo: [self displayImage: aOpenGLImage rOpO: rvpv + rpqv]</body>

<body package="CADSM-UI" selector="displayTiltHandle:">displayTiltHandle: aTiltHandle 
	"Add 0.01d to remove rounding jitter."

	| aOpenGLImage rOpO rpqv rvpv |
	aOpenGLImage := CADSMUIOpenGLImage aImage: aTiltHandle image.
	rOpO := aTiltHandle aSpatialItem aBoundingBox center.
	rvpv := (self rvpvFromrOpO: rOpO) plusNumber: 0.01d.
	aTiltHandle originPx: rvpv.
	rpqv := StMFullColumn 
				with: (aOpenGLImage width // 2 + 1) negated asDouble
				with: (aOpenGLImage height // 2) negated asDouble
				with: 0.0d.
	self inScreenCoordDo: 
			[self displayImage: aOpenGLImage rOpO: rvpv + rpqv.
			"self debugShow: (self rvpvFromrOpO: rvpv + rpqv)"]</body>

<body package="CADSM-UI" selector="perspectiveCorrectionHint">perspectiveCorrectionHint
	OpenGLInterface glHint: OpenGLInterface GL_PERSPECTIVE_CORRECTION_HINT
		with: OpenGLInterface GL_NICEST</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>scrolling</category>

<body package="CADSM-UI" selector="scrollCamera:by:">scrollCamera: aCamera by: aPoint 
	| rOpO crpqv rOqO |
	self parallelProjection: aCamera.
	rOpO := aCamera eyePoint.
	crpqv := OrderedCollection with: aPoint x negated @ aPoint y.
	rOqO := (self crOqOFromrOpO: rOpO crpqv: crpqv) first.
	aCamera eyePoint: rOqO</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>bounds</category>

<body package="CADSM-UI" selector="calcViewBoxFor:with:">calcViewBoxFor: aBoundingBox with: aCamera 
	| crOpO crvpv boundingBox |
	self parallelProjection: aCamera.
	crOpO := aBoundingBox cCorner.
	crvpv := self crvpvFromcrOpO: crOpO.
	boundingBox := CADSMMiscBoundingBox new.
	crvpv inject: boundingBox into: [:bbox :rvpv | bbox expandToBound: rvpv].
	^boundingBox</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>activation</category>

<body package="CADSM-UI" selector="activate:">activate: aBlock 
	^self critical: 
			[handle isNil ifTrue: [self basicRestoreHandle].
			handle isNil ifTrue: [^self error: 'Failed to restore rendering context'].
			ActiveContext == self 
				ifFalse: 
					[handle makeCurrent.
					ActiveContext := self].
			aBlock value]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>private</category>

<body package="CADSM-UI" selector="critical:">critical: aBlock 
	^CriticalSectionSemaphore critical: aBlock</body>

<body package="CADSM-UI" selector="displayFaceUse:displayMode1:">displayFaceUse: aFaceUse displayMode1: mode 
	| aNurbsSurface cuKnot cvKnot uSize vSize ccPoint ccWeight floatArray cuKnotPointer cvKnotPointer floatArrayPointer |
	aNurbsSurface := aFaceUse aNurbs.
	cuKnot := aNurbsSurface cuKnot collect: [:each | each asFloat].
	cvKnot := aNurbsSurface cvKnot collect: [:each | each asFloat].
	uSize := aNurbsSurface uSize.
	vSize := aNurbsSurface vSize.
	ccPoint := aNurbsSurface ccPoint.
	ccWeight := aNurbsSurface ccWeight.
	floatArray := WriteStream on: Array new.
	1 to: uSize
		do: 
			[:i | 
			| ccPointi ccWeighti |
			ccPointi := ccPoint at: i.
			ccWeighti := ccWeight at: i.
			1 to: vSize
				do: 
					[:j | 
					| pointij weightij |
					pointij := ccPointi at: j.
					weightij := ccWeighti at: j.
					floatArray nextPut: (pointij x * weightij) asFloat.
					floatArray nextPut: (pointij y * weightij) asFloat.
					floatArray nextPut: (pointij z * weightij) asFloat.
					floatArray nextPut: weightij asFloat]].
	floatArray := floatArray contents.
	cuKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cuKnot.
	cvKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cvKnot.
	floatArrayPointer := JunForeignHeap copyFloatArrayToGcHeap: floatArray.
	self activate: 
			[| aNurbsRenderer |
			self _enable: #GL_AUTO_NORMAL.
			aNurbsRenderer := OpenGLInterface gluNewNurbsRenderer.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_SAMPLING_TOLERANCE
				with: nurbsSamplingTolerance.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_DISPLAY_MODE
				with: mode.
			OpenGLInterface gluBeginSurface: aNurbsRenderer.
			OpenGLInterface 
				gluNurbsSurface: aNurbsRenderer
				with: cuKnot size
				with: cuKnotPointer
				with: cvKnot size
				with: cvKnotPointer
				with: 4 * vSize
				with: 4
				with: floatArrayPointer
				with: aNurbsSurface uOrder
				with: aNurbsSurface vOrder
				with: OpenGLInterface GL_MAP2_VERTEX_4.
			aFaceUse cLoopUse do: 
					[:aLoopUse | 
					self 
						displayTrimLoopUse: aLoopUse
						aNurbsSurface: aNurbsSurface
						aNurbsRenderer: aNurbsRenderer].
			OpenGLInterface gluEndSurface: aNurbsRenderer.
			OpenGLInterface gluDeleteNurbsRenderer: aNurbsRenderer].
	cuKnotPointer free.
	cvKnotPointer free.
	floatArrayPointer free</body>

<body package="CADSM-UI" selector="displayFaceUse:displayMode2:">displayFaceUse: aFaceUse displayMode2: mode 
	| aNurbsSurface cuKnot cvKnot uSize vSize ccPoint ccWeight floatArray cuKnotPointer cvKnotPointer floatArrayPointer |
	aFaceUse cLoopUse size &gt; 1 
		ifTrue: 
			[aNurbsSurface := aFaceUse aNurbs.
			cuKnot := aNurbsSurface cuKnot collect: [:each | each asFloat].
			cvKnot := aNurbsSurface cvKnot collect: [:each | each asFloat].
			uSize := aNurbsSurface uSize.
			vSize := aNurbsSurface vSize.
			ccPoint := aNurbsSurface ccPoint.
			ccWeight := aNurbsSurface ccWeight.
			floatArray := WriteStream on: Array new.
			1 to: uSize
				do: 
					[:i | 
					| ccPointi ccWeighti |
					ccPointi := ccPoint at: i.
					ccWeighti := ccWeight at: i.
					1 to: vSize
						do: 
							[:j | 
							| pointij weightij |
							pointij := ccPointi at: j.
							weightij := ccWeighti at: j.
							floatArray nextPut: (pointij x * weightij) asFloat.
							floatArray nextPut: (pointij y * weightij) asFloat.
							floatArray nextPut: (pointij z * weightij) asFloat.
							floatArray nextPut: weightij asFloat]].
			floatArray := floatArray contents.
			cuKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cuKnot.
			cvKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cvKnot.
			floatArrayPointer := JunForeignHeap copyFloatArrayToGcHeap: floatArray.
			self activate: 
					[| aNurbsRenderer |
					self _enable: #GL_AUTO_NORMAL.
					aNurbsRenderer := OpenGLInterface gluNewNurbsRenderer.
					OpenGLInterface 
						gluNurbsProperty: aNurbsRenderer
						with: OpenGLInterface GLU_SAMPLING_TOLERANCE
						with: nurbsSamplingTolerance.
					OpenGLInterface 
						gluNurbsProperty: aNurbsRenderer
						with: OpenGLInterface GLU_DISPLAY_MODE
						with: mode.
					OpenGLInterface gluBeginSurface: aNurbsRenderer.
					OpenGLInterface 
						gluNurbsSurface: aNurbsRenderer
						with: cuKnot size
						with: cuKnotPointer
						with: cvKnot size
						with: cvKnotPointer
						with: 4 * vSize
						with: 4
						with: floatArrayPointer
						with: aNurbsSurface uOrder
						with: aNurbsSurface vOrder
						with: OpenGLInterface GL_MAP2_VERTEX_4.
					aFaceUse cLoopUse do: 
							[:aLoopUse | 
							self 
								displayTrimLoopUse: aLoopUse
								aNurbsSurface: aNurbsSurface
								aNurbsRenderer: aNurbsRenderer].
					OpenGLInterface gluEndSurface: aNurbsRenderer.
					OpenGLInterface gluDeleteNurbsRenderer: aNurbsRenderer].
			cuKnotPointer free.
			cvKnotPointer free.
			floatArrayPointer free]</body>

<body package="CADSM-UI" selector="displayFaceUse:displayMode3:">displayFaceUse: aFaceUse displayMode3: mode 
	| aNurbsSurface cuKnot cvKnot uSize vSize ccPoint ccWeight floatArray cuKnotPointer cvKnotPointer floatArrayPointer |
	aNurbsSurface := aFaceUse glSurface.
	cuKnot := aNurbsSurface cuKnot collect: [:each | each asFloat].
	cvKnot := aNurbsSurface cvKnot collect: [:each | each asFloat].
	uSize := aNurbsSurface uSize.
	vSize := aNurbsSurface vSize.
	ccPoint := aNurbsSurface ccPoint.
	ccWeight := aNurbsSurface ccWeight.
	floatArray := WriteStream on: Array new.
	1 to: uSize
		do: 
			[:i | 
			| ccPointi ccWeighti |
			ccPointi := ccPoint at: i.
			ccWeighti := ccWeight at: i.
			1 to: vSize
				do: 
					[:j | 
					| pointij weightij |
					pointij := ccPointi at: j.
					weightij := ccWeighti at: j.
					floatArray nextPut: (pointij x * weightij) asFloat.
					floatArray nextPut: (pointij y * weightij) asFloat.
					floatArray nextPut: (pointij z * weightij) asFloat.
					floatArray nextPut: weightij asFloat]].
	floatArray := floatArray contents.
	cuKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cuKnot.
	cvKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cvKnot.
	floatArrayPointer := JunForeignHeap copyFloatArrayToGcHeap: floatArray.
	self activate: 
			[| aNurbsRenderer |
			self _enable: #GL_AUTO_NORMAL.
			aNurbsRenderer := OpenGLInterface gluNewNurbsRenderer.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_CULLING
				with: OpenGLInterface GLU_TRUE.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_SAMPLING_TOLERANCE
				with: nurbsSamplingTolerance.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_DISPLAY_MODE
				with: mode.
			OpenGLInterface gluBeginSurface: aNurbsRenderer.
			OpenGLInterface 
				gluNurbsSurface: aNurbsRenderer
				with: cuKnot size
				with: cuKnotPointer
				with: cvKnot size
				with: cvKnotPointer
				with: 4 * vSize
				with: 4
				with: floatArrayPointer
				with: aNurbsSurface uOrder
				with: aNurbsSurface vOrder
				with: OpenGLInterface GL_MAP2_VERTEX_4.
			aFaceUse cLoopUse do: 
					[:aLoopUse | 
					self 
						displayTrimLoopUse: aLoopUse
						aNurbsSurface: aNurbsSurface
						aNurbsRenderer: aNurbsRenderer].
			OpenGLInterface gluEndSurface: aNurbsRenderer.
			OpenGLInterface gluDeleteNurbsRenderer: aNurbsRenderer].
	cuKnotPointer free.
	cvKnotPointer free.
	floatArrayPointer free</body>

<body package="CADSM-UI" selector="displayFaceUse:displayMode4:">displayFaceUse: aFaceUse displayMode4: mode 
	| aNurbsSurface cuKnot cvKnot uSize vSize ccPoint ccWeight floatArray cuKnotPointer cvKnotPointer floatArrayPointer |
	aNurbsSurface := aFaceUse glSurface.
	cuKnot := aNurbsSurface cuKnot collect: [:each | each asFloat].
	cvKnot := aNurbsSurface cvKnot collect: [:each | each asFloat].
	uSize := aNurbsSurface uSize.
	vSize := aNurbsSurface vSize.
	ccPoint := aNurbsSurface ccPoint.
	ccWeight := aNurbsSurface ccWeight.
	floatArray := WriteStream on: Array new.
	1 to: uSize
		do: 
			[:i | 
			| ccPointi ccWeighti |
			ccPointi := ccPoint at: i.
			ccWeighti := ccWeight at: i.
			1 to: vSize
				do: 
					[:j | 
					| pointij weightij |
					pointij := ccPointi at: j.
					weightij := ccWeighti at: j.
					floatArray nextPut: (pointij x * weightij) asFloat.
					floatArray nextPut: (pointij y * weightij) asFloat.
					floatArray nextPut: (pointij z * weightij) asFloat.
					floatArray nextPut: weightij asFloat]].
	floatArray := floatArray contents.
	cuKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cuKnot.
	cvKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cvKnot.
	floatArrayPointer := JunForeignHeap copyFloatArrayToGcHeap: floatArray.
	self activate: 
			[| aNurbsRenderer |
			self _enable: #GL_AUTO_NORMAL.
			aNurbsRenderer := OpenGLInterface gluNewNurbsRenderer.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_CULLING
				with: OpenGLInterface GLU_TRUE.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_SAMPLING_TOLERANCE
				with: nurbsSamplingTolerance.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_DISPLAY_MODE
				with: mode.
			OpenGLInterface gluBeginSurface: aNurbsRenderer.
			OpenGLInterface 
				gluNurbsSurface: aNurbsRenderer
				with: cuKnot size
				with: cuKnotPointer
				with: cvKnot size
				with: cvKnotPointer
				with: 4 * vSize
				with: 4
				with: floatArrayPointer
				with: aNurbsSurface uOrder
				with: aNurbsSurface vOrder
				with: OpenGLInterface GL_MAP2_VERTEX_4.
					self 
						displayTrimLoopUse: aFaceUse cLoopUse first
						aNurbsSurface: aNurbsSurface
						aNurbsRenderer: aNurbsRenderer.
			OpenGLInterface gluEndSurface: aNurbsRenderer.
			OpenGLInterface gluDeleteNurbsRenderer: aNurbsRenderer].
	cuKnotPointer free.
	cvKnotPointer free.
	floatArrayPointer free</body>

<body package="CADSM-UI" selector="displayFaceUse:displayMode:">displayFaceUse: aFaceUse displayMode: mode 
	| aNurbsSurface cuKnot cvKnot uSize vSize ccPoint ccWeight floatArray cuKnotPointer cvKnotPointer floatArrayPointer |
	aNurbsSurface := aFaceUse glSurface.
	cuKnot := aNurbsSurface cuKnot collect: [:each | each asFloat].
	cvKnot := aNurbsSurface cvKnot collect: [:each | each asFloat].
	uSize := aNurbsSurface uSize.
	vSize := aNurbsSurface vSize.
	ccPoint := aNurbsSurface ccPoint.
	ccWeight := aNurbsSurface ccWeight.
	floatArray := WriteStream on: Array new.
	1 to: uSize
		do: 
			[:i | 
			| ccPointi ccWeighti |
			ccPointi := ccPoint at: i.
			ccWeighti := ccWeight at: i.
			1 to: vSize
				do: 
					[:j | 
					| pointij weightij |
					pointij := ccPointi at: j.
					weightij := ccWeighti at: j.
					floatArray nextPut: (pointij x * weightij) asFloat.
					floatArray nextPut: (pointij y * weightij) asFloat.
					floatArray nextPut: (pointij z * weightij) asFloat.
					floatArray nextPut: weightij asFloat]].
	floatArray := floatArray contents.
	cuKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cuKnot.
	cvKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cvKnot.
	floatArrayPointer := JunForeignHeap copyFloatArrayToGcHeap: floatArray.
	self activate: 
			[| aNurbsRenderer |
			self _enable: #GL_AUTO_NORMAL.
			aNurbsRenderer := OpenGLInterface gluNewNurbsRenderer.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_CULLING
				with: OpenGLInterface GLU_TRUE.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_SAMPLING_TOLERANCE
				with: nurbsSamplingTolerance.
			OpenGLInterface 
				gluNurbsProperty: aNurbsRenderer
				with: OpenGLInterface GLU_DISPLAY_MODE
				with: mode.
			OpenGLInterface gluBeginSurface: aNurbsRenderer.
			OpenGLInterface 
				gluNurbsSurface: aNurbsRenderer
				with: cuKnot size
				with: cuKnotPointer
				with: cvKnot size
				with: cvKnotPointer
				with: 4 * vSize
				with: 4
				with: floatArrayPointer
				with: aNurbsSurface uOrder
				with: aNurbsSurface vOrder
				with: OpenGLInterface GL_MAP2_VERTEX_4.
			aFaceUse ccglTrimNurbs do: 
					[:cglTrimNurbs | 
					OpenGLInterface gluBeginTrim: aNurbsRenderer.
					cglTrimNurbs do: 
							[:glTrimNurbs | 
							self 
								displayTrimNurbs: glTrimNurbs
								aNurbsSurface: aNurbsSurface
								aNurbsRenderer: aNurbsRenderer].
					OpenGLInterface gluEndTrim: aNurbsRenderer].
			OpenGLInterface gluEndSurface: aNurbsRenderer.
			OpenGLInterface gluDeleteNurbsRenderer: aNurbsRenderer].
	cuKnotPointer free.
	cvKnotPointer free.
	floatArrayPointer free</body>

<body package="CADSM-UI" selector="displayNurbsSurface:displayMode:">displayNurbsSurface: aNurbsSurface displayMode: mode 
	| aNurbs uKnotVector vKnotVector floatArray uSize vSize |
	uKnotVector := aNurbsSurface uKnotVector collect: [:each | each asFloat].
	vKnotVector := aNurbsSurface vKnotVector collect: [:each | each asFloat].
	uSize := aNurbsSurface uSize.
	vSize := aNurbsSurface vSize.
	floatArray := WriteStream on: Array new.
	1 to: uSize
		do: 
			[:uIndex | 
			1 to: vSize
				do: 
					[:vIndex | 
					| point weight |
					point := aNurbsSurface controlPointAtU: uIndex v: vIndex.
					weight := aNurbsSurface weightAtU: uIndex v: vIndex.
					floatArray nextPut: (point x * weight) asFloat.
					floatArray nextPut: (point y * weight) asFloat.
					floatArray nextPut: (point z * weight) asFloat.
					floatArray nextPut: weight asFloat]].
	floatArray := floatArray contents.
	self activate: 
			[self _enable: #GL_AUTO_NORMAL.
			aNurbs := OpenGLInterface gluNewNurbsRenderer.
			OpenGLInterface 
				gluNurbsProperty: aNurbs
				with: OpenGLInterface GLU_SAMPLING_TOLERANCE
				with: nurbsSamplingTolerance.
			OpenGLInterface 
				gluNurbsProperty: aNurbs
				with: OpenGLInterface GLU_DISPLAY_MODE
				with: mode.
			OpenGLInterface glPushMatrix.
			OpenGLInterface gluBeginSurface: aNurbs.
			OpenGLInterface 
				gluNurbsSurface: aNurbs
				with: uKnotVector size
				with: (JunForeignHeap copyFloatArrayToGcHeap: uKnotVector)
				with: vKnotVector size
				with: (JunForeignHeap copyFloatArrayToGcHeap: vKnotVector)
				with: 4 * vSize
				with: 4
				with: (JunForeignHeap copyFloatArrayToGcHeap: floatArray)
				with: aNurbsSurface uOrder
				with: aNurbsSurface vOrder
				with: OpenGLInterface GL_MAP2_VERTEX_4.
			aNurbsSurface trimCurvesDo: 
					[:trimCurve | 
					trimCurve 
						renderOn: self
						with: aNurbsSurface
						for: aNurbs].
			OpenGLInterface gluEndSurface: aNurbs.
			OpenGLInterface glPopMatrix.
			OpenGLInterface gluDeleteNurbsRenderer: aNurbs]</body>

<body package="CADSM-UI" selector="toTranscriptShowError">toTranscriptShowError
	| errNum string |
	errNum := OpenGLInterface glGetError.
	errNum = OpenGLInterface GL_NO_ERROR 
		ifFalse: 
			[string := (OpenGLInterface gluErrorString: errNum) copyCStringFromHeap.
			self toTranscriptShow: string]</body>

<body package="CADSM-UI" selector="trimNurbsCurve:for:">trimNurbsCurve: aNurbsCurve for: aNurbsHandle 
	| knotVector controlPoints weights floatArray |
	knotVector := aNurbsCurve knotVector collect: [:each | each asFloat].
	controlPoints := aNurbsCurve controlPoints.
	weights := aNurbsCurve weights.
	floatArray := WriteStream on: Array new.
	controlPoints with: weights
		do: 
			[:point :weight | 
			floatArray nextPut: (point x * weight) asFloat.
			floatArray nextPut: (point y * weight) asFloat.
			floatArray nextPut: weight asFloat].
	floatArray := floatArray contents.
	OpenGLInterface gluBeginTrim: aNurbsHandle.
	OpenGLInterface 
		gluNurbsCurve: aNurbsHandle
		with: knotVector size
		with: (JunForeignHeap copyFloatArrayToGcHeap: knotVector)
		with: 3
		with: (JunForeignHeap copyFloatArrayToGcHeap: floatArray)
		with: aNurbsCurve order
		with: OpenGLInterface GLU_MAP1_TRIM_3.
	OpenGLInterface gluEndTrim: aNurbsHandle</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>projection</category>

<body package="CADSM-UI" selector="crOqOFromrOpO:crpqv1:">crOqOFromrOpO: rOpO crpqv1: crpqv 
	"
	Given rOpO =  r from O to p in O components.
	Given collection of rpqv.
	rpqv = r from p to q in viewport components.
	Answer collection of rOqO.
	"

	^self activate: 
			[| viewportPointer modelviewPointer projectionPointer rvpv1Pointer rvpv2Pointer rvpv3Pointer rvpv1 rvpv2 rvpv3 rOqO1Pointer rOqO2Pointer rOqO3Pointer answer |
			modelviewPointer := CLimitedPrecisionRealType double gcMalloc: 16.
			projectionPointer := CLimitedPrecisionRealType double gcMalloc: 16.
			viewportPointer := CIntegerType long gcMalloc: 4.
			OpenGLInterface glGetDoublev: OpenGLInterface GL_MODELVIEW_MATRIX
				with: modelviewPointer.
			OpenGLInterface glGetDoublev: OpenGLInterface GL_PROJECTION_MATRIX
				with: projectionPointer.
			OpenGLInterface glGetIntegerv: OpenGLInterface GL_VIEWPORT
				with: viewportPointer.
			rvpv1Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			rvpv2Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			rvpv3Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			OpenGLInterface 
				gluProject: rOpO x asDouble
				with: rOpO y asDouble
				with: rOpO z asDouble
				with: modelviewPointer
				with: projectionPointer
				with: viewportPointer
				with: rvpv1Pointer
				with: rvpv2Pointer
				with: rvpv3Pointer.
			rvpv1 := rvpv1Pointer contents.
			rvpv2 := rvpv2Pointer contents.
			rvpv3 := rvpv3Pointer contents.
			rOqO1Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			rOqO2Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			rOqO3Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			answer := crpqv collect: 
							[:rpqv | 
							OpenGLInterface 
								gluUnProject: rvpv1 + rpqv x
								with: rvpv2 + rpqv y
								with: rvpv3
								with: modelviewPointer
								with: projectionPointer
								with: viewportPointer
								with: rOqO1Pointer
								with: rOqO2Pointer
								with: rOqO3Pointer.
							StCAD.StMath.StMFullColumn 
								with: rOqO1Pointer contents
								with: rOqO2Pointer contents
								with: rOqO3Pointer contents].
			answer]</body>

<body package="CADSM-UI" selector="crOqOFromrOpO:crpqv2:">crOqOFromrOpO: rOpO crpqv2: crpqv 
	"
	Given rOpO =  r from O to p in O components.
	Given collection of rpqv.
	rpqv = r from p to q in viewport components.
	Answer collection of rOqO.
	"

	| rvpv |
	rvpv := self rvpvFromrOpO: rOpO.
	^self activate: 
			[| rvpv1 rvpv2 rvpv3 rOqO1Pointer rOqO2Pointer rOqO3Pointer answer |
			rvpv1 := rvpv at: 1.
			rvpv2 := rvpv at: 2.
			rvpv3 := rvpv at: 3.
			rOqO1Pointer := cDoubleCPointer.
			rOqO2Pointer := cDoubleCPointer + 1.
			rOqO3Pointer := cDoubleCPointer + 2.
			answer := crpqv collect: 
							[:rpqv | 
							OpenGLInterface 
								gluUnProject: rvpv1 + rpqv x
								with: rvpv2 + rpqv y
								with: rvpv3
								with: modelviewCPointer
								with: projectionCPointer
								with: viewportCPointer
								with: rOqO1Pointer
								with: rOqO2Pointer
								with: rOqO3Pointer.
							StCAD.StMath.StMFullColumn 
								with: rOqO1Pointer contents
								with: rOqO2Pointer contents
								with: rOqO3Pointer contents].
			answer]</body>

<body package="CADSM-UI" selector="crOqOFromrOpO:crpqv:">crOqOFromrOpO: rOpO crpqv: crpqv 
	"
	Given rOpO =  r from O to p in O components.
	Given collection of rpqv.
	rpqv = r from p to q in viewport components.
	Answer collection of rOqO.
	"

	| rvpv |
	rvpv := self rvpvFromrOpO: rOpO.
	^self activate: 
			[| rvpv1 rvpv2 rvpv3 rOqO1Pointer rOqO2Pointer rOqO3Pointer answer |
			rvpv1 := rvpv at: 1.
			rvpv2 := rvpv at: 2.
			rvpv3 := rvpv at: 3.
			rOqO1Pointer := cDoubleCPointer.
			rOqO2Pointer := cDoubleCPointer + 1.
			rOqO3Pointer := cDoubleCPointer + 2.
			answer := crpqv collect: 
							[:rpqv | 
							OpenGLInterface 
								gluUnProject: rvpv1 + rpqv x
								with: rvpv2 + rpqv y
								with: rvpv3
								with: modelviewCPointer
								with: projectionCPointer
								with: viewportCPointer
								with: rOqO1Pointer
								with: rOqO2Pointer
								with: rOqO3Pointer.
							StCAD.StMath.StMFullColumn 
								with: rOqO1Pointer contents
								with: rOqO2Pointer contents
								with: rOqO3Pointer contents].
			answer]</body>

<body package="CADSM-UI" selector="crvpvFromcrOpO1:">crvpvFromcrOpO1: crOpO 
	"
	Given collection of rOpO.
	rOpO =  r from O to p in O components.
	Answer collection of rvpv.
	"

	^self activate: 
			[| modelviewPointer projectionPointer viewportPointer rvpv1Pointer rvpv2Pointer rvpv3Pointer answer |
			modelviewPointer := CLimitedPrecisionRealType double gcMalloc: 16.
			projectionPointer := CLimitedPrecisionRealType double gcMalloc: 16.
			viewportPointer := CIntegerType long gcMalloc: 4.
			OpenGLInterface glGetDoublev: OpenGLInterface GL_MODELVIEW_MATRIX
				with: modelviewPointer.
			OpenGLInterface glGetDoublev: OpenGLInterface GL_PROJECTION_MATRIX
				with: projectionPointer.
			OpenGLInterface glGetIntegerv: OpenGLInterface GL_VIEWPORT
				with: viewportPointer.
			rvpv1Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			rvpv2Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			rvpv3Pointer := CLimitedPrecisionRealType double gcMalloc: 1.
			answer := crOpO collect: 
							[:rOpO | 
							OpenGLInterface 
								gluProject: rOpO x asDouble
								with: rOpO y asDouble
								with: rOpO z asDouble
								with: modelviewPointer
								with: projectionPointer
								with: viewportPointer
								with: rvpv1Pointer
								with: rvpv2Pointer
								with: rvpv3Pointer.
							StCAD.StMath.StMFullColumn 
								with: rvpv1Pointer contents
								with: rvpv2Pointer contents
								with: rvpv3Pointer contents].
			answer]</body>

<body package="CADSM-UI" selector="crvpvFromcrOpO:">crvpvFromcrOpO: crOpO 
	"
	Given collection of rOpO.
	rOpO =  r from O to p in O components.
	Answer collection of rvpv.
	"

	^self activate: 
			[| rvpv1Pointer rvpv2Pointer rvpv3Pointer answer |
			OpenGLInterface glGetDoublev: OpenGLInterface GL_MODELVIEW_MATRIX
				with: modelviewCPointer.
			OpenGLInterface glGetDoublev: OpenGLInterface GL_PROJECTION_MATRIX
				with: projectionCPointer.
			"self debugShow: projectionCPointer contents."
			OpenGLInterface glGetIntegerv: OpenGLInterface GL_VIEWPORT
				with: viewportCPointer.
			rvpv1Pointer := cDoubleCPointer.
			rvpv2Pointer := cDoubleCPointer + 1.
			rvpv3Pointer := cDoubleCPointer + 2.
			answer := crOpO collect: 
							[:rOpO | 
							OpenGLInterface 
								gluProject: rOpO x asDouble
								with: rOpO y asDouble
								with: rOpO z asDouble
								with: modelviewCPointer
								with: projectionCPointer
								with: viewportCPointer
								with: rvpv1Pointer
								with: rvpv2Pointer
								with: rvpv3Pointer.
							StCAD.StMath.StMFullColumn 
								with: rvpv1Pointer contents
								with: rvpv2Pointer contents
								with: rvpv3Pointer contents].
			answer]</body>

<body package="CADSM-UI" selector="obeyCamera:">obeyCamera: aCamera 
	self perform: aCamera shading.
	self disableLineSmooth.
	self disablePolygonSmooth.
	self disableBlending.
	aCamera lineSmooth 
		ifTrue: 
			[self lineSmoothNicest.
			self enableLineSmooth.
			self enableBlending].
	aCamera polygonSmooth 
		ifTrue: 
			[self polygonSmoothFastest.
			self enablePolygonSmooth.
			self enableBlending]</body>

<body package="CADSM-UI" selector="obeyParallelCamera:">obeyParallelCamera: aCamera 
	self obeyCamera: aCamera.
	self parallelProjection: aCamera.
	self flush</body>

<body package="CADSM-UI" selector="obeyPerspectiveCamera:">obeyPerspectiveCamera: aCamera 
	self obeyCamera: aCamera.
	self perspectiveCorrectionHint.
	self perspective: aCamera.
	self flush</body>

<body package="CADSM-UI" selector="parallelProjection:">parallelProjection: aCamera 
	| aspect halfHeight halfWidth left right bottom top |
	self setProjection: aCamera copy.
	aCamera isPerspective 
		ifTrue: 
			[aspect := (viewport width / viewport height) asDouble.
			halfHeight := projection height / 2.
			halfWidth := halfHeight * aspect.
			left := halfWidth negated.
			right := halfWidth.
			bottom := halfHeight negated.
			top := halfHeight]
		ifFalse: 
			[left := projection left.
			right := projection right.
			bottom := projection bottom.
			top := projection top].
	self activate: 
			[OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface 
				glOrtho: left
				with: right
				with: bottom
				with: top
				with: projection near
				with: projection far.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface 
				gluLookAt: projection eyePoint x
				with: projection eyePoint y
				with: projection eyePoint z
				with: projection sightPoint x
				with: projection sightPoint y
				with: projection sightPoint z
				with: projection upVector x
				with: projection upVector y
				with: projection upVector z]</body>

<body package="CADSM-UI" selector="rOqOFromrOpO:rpqv:">rOqOFromrOpO: rOpO rpqv: rpqv 
	^(self crOqOFromrOpO: rOpO crpqv: (Array with: rpqv)) at: 1</body>

<body package="CADSM-UI" selector="rvpvFromrOpO:">rvpvFromrOpO: rOpO 
	^(self crvpvFromcrOpO: (Array with: rOpO)) at: 1</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	modelviewCPointer := OpenGLInterface GLdouble gcMalloc: 16.
	projectionCPointer := OpenGLInterface GLdouble gcMalloc: 16.
	viewportCPointer := OpenGLInterface GLint gcMalloc: 4.
	cDoubleCPointer := OpenGLInterface GLdouble gcMalloc: 4</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>transformation</category>

<body package="CADSM-UI" selector="inScreenCoordDo1:">inScreenCoordDo1: aBlock 
	self activate: 
			[OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
			OpenGLInterface glPushMatrix.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface 
				gluOrtho2D: 0.0d
				with: medium extent x asDouble
				with: 0.0d
				with: medium extent y asDouble.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
			OpenGLInterface glPushMatrix.
			OpenGLInterface glLoadIdentity].
	aBlock ensure: 
			[self activate: 
					[OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
					OpenGLInterface glPopMatrix.
					OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
					OpenGLInterface glPopMatrix]]</body>

<body package="CADSM-UI" selector="inScreenCoordDo:">inScreenCoordDo: aBlock 
	self activate: 
			[OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
			OpenGLInterface glPushMatrix.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface 
				glOrtho: 1.0d
				with: medium extent x asDouble
				with: 1.0d
				with: medium extent y asDouble
				with: -100.0d
				with: 100.0d.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
			OpenGLInterface glPushMatrix.
			OpenGLInterface glLoadIdentity].
	aBlock ensure: 
			[self activate: 
					[OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
					OpenGLInterface glPopMatrix.
					OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
					OpenGLInterface glPopMatrix]]</body>

<body package="CADSM-UI" selector="pushName:transformation:while:">pushName: aName transformation: aMFf while: aBlock 
	aName ifNil: 
			[aMFf ifNil: [aBlock value]
				ifNotNil: [self pushTransformation: aMFf while: aBlock]]
		ifNotNil: 
			[aMFf ifNil: [self pushName: aName while: aBlock]
				ifNotNil: 
					[self pushName: aName while: [self pushTransformation: aMFf while: aBlock]]]</body>

<body package="CADSM-UI" selector="pushName:while:">pushName: aName while: aBlock 
	self activate: [OpenGLInterface glPushName: aName hash].
	aBlock ensure: [self activate: [OpenGLInterface glPopName]]</body>

<body package="CADSM-UI" selector="pushTransformation:while:">pushTransformation: aMFf while: aBlock 
	| origTransformation matrixPointer |
	origTransformation := transformation.
	transformation := aMFf product: transformation.
	matrixPointer := JunForeignHeap copyDoubleArrayToGcHeap: aMFf asArray.
	self activate: 
			[OpenGLInterface glPushMatrix.
			OpenGLInterface glMultMatrixd: matrixPointer].
	matrixPointer free.
	aBlock ensure: 
			[self activate: [OpenGLInterface glPopMatrix].
			transformation := origTransformation]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>As yet unclassified</category>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer00:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer00: aNurbsRenderer 
	| cPoint aPoint bPoint aNurbs |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	cPoint := OrderedCollection new.
	cPoint 
		add: (StMFullColumn newWithElements: #(0.89306376501028d 0.05286776856637d)).
	cPoint add: (StMFullColumn 
				newWithElements: #(0.91051005031531d 0.050416305423135d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.55956198999169d 0.12434274142751d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.32822830038302d 0.21341458877918d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.31864019344699d 0.50710408340249d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.29910843245846d 0.74126103634664d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.29862089017272d 0.74845943579944d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.85355642432794d 0.96640565341161d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.99473935872219d 0.98882289731593d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.72410380782429d 0.99898389640984d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.5910902646662d 0.97512508160207d)).
	cPoint add: (StMFullColumn 
				newWithElements: #(0.0052606413749663d 0.76453788056835d)).
	cPoint add: (StMFullColumn 
				newWithElements: #(0.0052606412602262d 0.25425883608951d)).
	cPoint add: (StMFullColumn 
				newWithElements: #(0.36096422706368d 0.090423628771569d)).
	cPoint 
		add: (StMFullColumn newWithElements: #(0.5910902647298d 0.043671635072852d)).
	cPoint add: (StMFullColumn 
				newWithElements: #(0.82889601567772d 0.0010161035901582d)).
	cPoint add: cPoint first.
	aPoint := cPoint first.
	2 to: cPoint size
		do: 
			[:i | 
			bPoint := cPoint at: i.
			aNurbs := CADSMGeoNurbsCurve fromStart: aPoint copy toEnd: bPoint copy.
			aPoint := bPoint.
			self 
				displayTrimNurbs: aNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer0:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer0: aNurbsRenderer 
	| cPoint aPoint bPoint aNurbs |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	cPoint := OrderedCollection new.
	cPoint add: (StMFullColumn with: 0.0d with: 0.0d).
	cPoint add: (StMFullColumn with: 1.0d with: 0.0d).
	cPoint add: (StMFullColumn with: 1.0d with: 1.0d).
	cPoint add: (StMFullColumn with: 0.0d with: 1.0d).
	cPoint add: cPoint first.
	aPoint := cPoint first.
	2 to: cPoint size
		do: 
			[:i | 
			bPoint := cPoint at: i.
			aNurbs := CADSMGeoNurbsCurve fromStart: aPoint copy toEnd: bPoint copy.
			aPoint := bPoint.
			self 
				displayTrimNurbs: aNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer1:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer1: aNurbsRenderer 
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	aLoopUse cglTrimNurbs do: 
			[:glTrimNurbs | 
			self 
				displayTrimNurbs: glTrimNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer2:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer2: aNurbsRenderer 
	| cPoint aNurbs |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	cPoint := OrderedCollection new.
	cPoint add: (StMFullColumn with: 0.0d with: 0.0d).
	cPoint add: (StMFullColumn with: 1.0d with: 0.0d).
	cPoint add: (StMFullColumn with: 1.0d with: 1.0d).
	cPoint add: (StMFullColumn with: 0.0d with: 1.0d).
	cPoint add: cPoint first.
	aNurbs := CADSMGeoNurbsCurve fromcDataPoint: cPoint uDegree: 1.
	self 
		displayTrimNurbs: aNurbs
		aNurbsSurface: aNurbsSurface
		aNurbsRenderer: aNurbsRenderer.
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer3:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer3: aNurbsRenderer 
	| aStream cglTrimNurbs aNurbs |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	aStream := (StMFullColumn new: 10) writeStream.
	cglTrimNurbs := aLoopUse cglTrimNurbs.
	cglTrimNurbs 
		do: [:glTrimNurbs | aStream nextPut: glTrimNurbs cPoint first copy].
	aStream nextPut: cglTrimNurbs first cPoint first copy.
	aNurbs := CADSMGeoNurbsCurve fromcDataPoint: aStream contents uDegree: 1.
	self 
		displayTrimNurbs: aNurbs
		aNurbsSurface: aNurbsSurface
		aNurbsRenderer: aNurbsRenderer.
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer4:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer4: aNurbsRenderer 
	| tol uvStart uvEnd cNurbs v aPoint bPoint cPoint dPoint |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	aLoopUse cEdgeUse do: 
			[:aEdgeUse | 
			aEdgeUse glNurbs cLineNurbs do: 
					[:aLine | 
					self 
						displayTrimNurbs: aLine
						aNurbsSurface: aNurbsSurface
						aNurbsRenderer: aNurbsRenderer]].
	tol := 1.0d-9.
	uvStart := aLoopUse uvStart.
	uvEnd := aLoopUse uvEnd.
	(uvStart - uvEnd) length &lt; tol 
		ifFalse: 
			[(aLoopUse aSurface isMemberOf: CADSMGeoSphericalSurface) 
				ifTrue: 
					[cNurbs := OrderedCollection new: 3.
					v := uvStart u &lt; uvEnd u ifTrue: [1.0d] ifFalse: [0.0d].
					aPoint := uvEnd.
					bPoint := StMFullColumn with: uvEnd u with: v.
					cPoint := StMFullColumn with: uvStart u with: v.
					dPoint := uvStart.
					cNurbs add: (CADSMGeoNurbsCurve fromStart: aPoint copy toEnd: bPoint copy).
					cNurbs add: (CADSMGeoNurbsCurve fromStart: bPoint copy toEnd: cPoint copy).
					cNurbs add: (CADSMGeoNurbsCurve fromStart: cPoint copy toEnd: dPoint copy).
					cNurbs do: 
							[:aNurbs | 
							self 
								displayTrimNurbs: aNurbs
								aNurbsSurface: aNurbsSurface
								aNurbsRenderer: aNurbsRenderer]]
				ifFalse: [self assert: [false]]].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer5:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer5: aNurbsRenderer 
	| cEdgeUse n glNurbs |
	cEdgeUse := aLoopUse cEdgeUse.
	n := cEdgeUse size.
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	cEdgeUse := aLoopUse cEdgeUse.
	1 to: n
		do: 
			[:i | 
			| aEdgeUse |
			aEdgeUse := cEdgeUse at: i.
			glNurbs := ((n = 2 
						ifTrue: [#()	"1"	"2"]
						ifFalse: [#(2 4 6 8 10 12 14 16)	"1"	"3"	"5"	"7"	"9"	"11"	"13"	"15"]) 
							includes: i) 
							ifTrue: [CADSMGeoNurbsCurve fromStart: aEdgeUse uvStart toEnd: aEdgeUse uvEnd]
							ifFalse: [aEdgeUse glNurbs].
			self 
				displayTrimNurbs: glNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer6:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer6: aNurbsRenderer 
	| cglTrimNurbs n uvStart uvEnd |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	cglTrimNurbs := aLoopUse cglTrimNurbs.
	n := cglTrimNurbs size.
	1 to: n
		do: 
			[:i | 
			| glTrimNurbs |
			glTrimNurbs := i = 1 
						ifTrue: [cglTrimNurbs at: i]
						ifFalse: 
							[uvStart := (cglTrimNurbs at: (i - 1 cyclic: n)) cPoint last.
							uvEnd := (cglTrimNurbs at: (i + 1 cyclic: n)) cPoint first.
							CADSMGeoNurbsCurve fromStart: uvStart toEnd: uvEnd].
			self 
				displayTrimNurbs: glTrimNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer7:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer7: aNurbsRenderer 
	| cglTrimNurbs n uvStart uvEnd |
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	cglTrimNurbs := aLoopUse cglTrimNurbs.
	n := cglTrimNurbs size.
	1 to: n
		do: 
			[:i | 
			| glTrimNurbs |
			glTrimNurbs := i = 1 
						ifTrue: 
							[uvStart := (cglTrimNurbs at: (i - 1 cyclic: n)) cPoint last.
							uvEnd := (cglTrimNurbs at: (i + 1 cyclic: n)) cPoint first.
							CADSMGeoNurbsCurve fromStart: uvStart toEnd: uvEnd]
						ifFalse: [cglTrimNurbs at: i].
			self 
				displayTrimNurbs: glTrimNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer8:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer8: aNurbsRenderer 
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	aLoopUse cglTrimNurbs do: 
			[:glTrimNurbs | 
			self 
				displayTrimNurbs: glTrimNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimLoopUse:aNurbsSurface:aNurbsRenderer:">displayTrimLoopUse: aLoopUse aNurbsSurface: aNurbsSurface aNurbsRenderer: aNurbsRenderer 
	OpenGLInterface gluBeginTrim: aNurbsRenderer.
	aLoopUse cglTrimNurbs do: 
			[:glTrimNurbs | 
			self 
				displayTrimNurbs: glTrimNurbs
				aNurbsSurface: aNurbsSurface
				aNurbsRenderer: aNurbsRenderer].
	OpenGLInterface gluEndTrim: aNurbsRenderer</body>

<body package="CADSM-UI" selector="displayTrimNurbs:aNurbsSurface:aNurbsRenderer:">displayTrimNurbs: aNurbsCurve aNurbsSurface: aNurbsSurface aNurbsRenderer: aNurbsRenderer 
	| cuKnot cPoint cWeight floatArray cuKnotPointer floatArrayPointer |
	cuKnot := aNurbsCurve cuKnot collect: [:each | each asFloat].
	cPoint := aNurbsCurve cPoint.
	cWeight := aNurbsCurve cWeight.
	floatArray := WriteStream on: Array new.
	1 to: cPoint size
		do: 
			[:i | 
			| point weight |
			point := cPoint at: i.
			weight := cWeight at: i.
			floatArray nextPut: (point x * weight) asFloat.
			floatArray nextPut: (point y * weight) asFloat.
			floatArray nextPut: weight asFloat].
	floatArray := floatArray contents.
	cuKnotPointer := JunForeignHeap copyFloatArrayToGcHeap: cuKnot.
	floatArrayPointer := JunForeignHeap copyFloatArrayToGcHeap: floatArray.
	OpenGLInterface 
		gluNurbsCurve: aNurbsRenderer
		with: cuKnot size
		with: cuKnotPointer
		with: 3
		with: floatArrayPointer
		with: aNurbsCurve order
		with: OpenGLInterface GLU_MAP1_TRIM_3.
	cuKnotPointer free.
	floatArrayPointer free</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>defaults</category>

<body package="CADSM-UI" selector="defaultNurbsSamplingTolerance">defaultNurbsSamplingTolerance
	^8.0</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLRenderingContext</class-id> <category>display list</category>

<body package="CADSM-UI" selector="isDisplayList:">isDisplayList: anInteger 
	| integer |
	integer := self activate: [OpenGLInterface glIsList: anInteger].
	^integer == 1 
		ifTrue: [true]
		ifFalse: [integer == 0 ifTrue: [false] ifFalse: [self halt: 'check this']]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>projecting</category>

<body package="CADSM-UI" selector="perspective:">perspective: aJunOpenGLPerspective 
	self
		activate: 
			[self setProjection: aJunOpenGLPerspective copy.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface
				gluPerspective: self projection fovy deg asDouble
				with: (viewport width / viewport height) asDouble
				with: projection near
				with: projection far.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface
				gluLookAt: projection eyePoint x
				with: projection eyePoint y
				with: projection eyePoint z
				with: projection sightPoint x
				with: projection sightPoint y
				with: projection sightPoint z
				with: projection upVector x
				with: projection upVector y
				with: projection upVector z]</body>

<body package="CADSM-UI" selector="pickAt:aPerspectiveCamera:">pickAt: rvGLpvGL aPerspectiveCamera: aPerspectiveCamera 
	self activate: 
			[self setProjection: aPerspectiveCamera copy.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_PROJECTION.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface glGetIntegerv: OpenGLInterface GL_VIEWPORT
				with: viewportCPointer.
			OpenGLInterface 
				gluPickMatrix: rvGLpvGL x asDouble
				with: rvGLpvGL y asDouble
				with: 10 asDouble
				with: 10 asDouble
				with: viewportCPointer.
			OpenGLInterface 
				gluPerspective: self projection fovy deg asDouble
				with: (viewport width / viewport height) asDouble
				with: projection near
				with: projection far.
			OpenGLInterface glMatrixMode: OpenGLInterface GL_MODELVIEW.
			OpenGLInterface glLoadIdentity.
			OpenGLInterface 
				gluLookAt: projection eyePoint x
				with: projection eyePoint y
				with: projection eyePoint z
				with: projection sightPoint x
				with: projection sightPoint y
				with: projection sightPoint z
				with: projection upVector x
				with: projection upVector y
				with: projection upVector z]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="clearColorBuffer">clearColorBuffer</body>

<body package="CADSM-UI" selector="displayPolygon:">displayPolygon: aCollectionOfPoints 
	self
		activate: 
			[OpenGLInterface glBegin: OpenGLInterface GL_POLYGON.
			aCollectionOfPoints do: [:a3dPoint | OpenGLInterface
					glVertex3d: a3dPoint x asDouble
					with: a3dPoint y asDouble
					with: a3dPoint z asDouble].
			OpenGLInterface glEnd]</body>

<body package="CADSM-UI" selector="pickAt:aCamera:">pickAt: rvGLpvGL aCamera: aCamera 
	^aCamera pickAt: rvGLpvGL aContext: self</body>

<body package="CADSM-UI" selector="pickAt:aCamera:aModel:">pickAt: rvGLpvGL aCamera: aCamera aModel: aModel 
	self selectionBufferSize: 1024.
	self pickAt: rvGLpvGL aCamera: aCamera.
	^self selectNearestObjectWhile: 
			[aModel renderOn: self.
			self flush]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>selecting</category>

<body package="CADSM-UI" selector="selectNearestObjectWhile:">selectNearestObjectWhile: aBlock 
	| selectionBuffer |
	
	[| bufferSize status maxIndex pickedIndex pickedDepth index offset |
	bufferSize := self selectionBufferSize.
	selectionBuffer := OpenGLInterface GLuint malloc: bufferSize.
	self activate: 
			[OpenGLInterface glSelectBuffer: bufferSize with: selectionBuffer.
			OpenGLInterface glRenderMode: OpenGLInterface GL_SELECT.
			OpenGLInterface glInitNames.
			OpenGLInterface glPushName: 0].
	aBlock value.
	self 
		activate: [status := OpenGLInterface glRenderMode: OpenGLInterface GL_RENDER].
	self toTranscriptShow: status.
	maxIndex := status ~= -1 ifTrue: [status] ifFalse: [bufferSize].
	pickedIndex := 0.
	pickedDepth := self maxID.
	index := 1.
	offset := 0.
	[index &lt;= maxIndex] whileTrue: 
			[| numNames minDepth name |
			numNames := selectionBuffer at: offset.
			minDepth := selectionBuffer at: offset + 1.
			name := selectionBuffer at: offset + 3.
			minDepth &lt; pickedDepth 
				ifTrue: 
					[pickedIndex := name.
					pickedDepth := minDepth].
			offset := offset + 3 + numNames.
			index := index + 1].
	^pickedIndex &gt; 0 ifTrue: [pickedIndex] ifFalse: [nil]] 
			ensure: [selectionBuffer notNil ifTrue: [selectionBuffer free]]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	super initialize.
	super disableBlending.
	super disableLighting.
	super disableFog.
	super disablePolygonSmooth.
	super disableLineSmooth.
	super flatShading.
	super disableNormalize.
	super disableDithering.
	super enableDepthTest.
	self selectionBufferSize: self defaultSelectionBufferSize</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="paint:alpha:">paint: aPaint alpha: aNumber
	paint := aPaint.
	alpha := aNumber asFloat.</body>

<body package="CADSM-UI" selector="selectionBufferSize">selectionBufferSize
	^selectionBufferSize</body>

<body package="CADSM-UI" selector="selectionBufferSize:">selectionBufferSize: anInteger 
	selectionBufferSize := anInteger rounded abs max: 1</body>

<body package="CADSM-UI" selector="setId:">setId: anInteger 
	self activate: [OpenGLInterface glLoadName: anInteger \\ self maxID]</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>blending</category>

<body package="CADSM-UI" selector="disableBlending">disableBlending</body>

<body package="CADSM-UI" selector="enableBlending">enableBlending</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>defaults</category>

<body package="CADSM-UI" selector="defaultSelectionBufferSize">defaultSelectionBufferSize
	^1024</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>dithering</category>

<body package="CADSM-UI" selector="disableDithering">disableDithering</body>

<body package="CADSM-UI" selector="enableDithering">enableDithering</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>fogging</category>

<body package="CADSM-UI" selector="disableFog">disableFog</body>

<body package="CADSM-UI" selector="enableFog">enableFog</body>

<body package="CADSM-UI" selector="fogColor:">fogColor: aColorValue</body>

<body package="CADSM-UI" selector="fogExp2Density:">fogExp2Density: aNumber</body>

<body package="CADSM-UI" selector="fogExpDensity:">fogExpDensity: aNumber</body>

<body package="CADSM-UI" selector="fogLinearStartDensity:endDensity:">fogLinearStartDensity: aNumber1 endDensity: aNumber2</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>lighting</category>

<body package="CADSM-UI" selector="diableLightIndex:">diableLightIndex: index0to7</body>

<body package="CADSM-UI" selector="disableLighting">disableLighting</body>

<body package="CADSM-UI" selector="enableLightIndex:">enableLightIndex: index0to7</body>

<body package="CADSM-UI" selector="enableLighting">enableLighting</body>

<body package="CADSM-UI" selector="lightAmbientColor:">lightAmbientColor: aColorValue</body>

<body package="CADSM-UI" selector="lightAmbientColor:alpha:">lightAmbientColor: aColorValue alpha: aNumber</body>

<body package="CADSM-UI" selector="lightAmbientColor:alpha:twoSide:">lightAmbientColor: aColorValue alpha: aNumber twoSide: aBoolean</body>

<body package="CADSM-UI" selector="lightIndex:position:">lightIndex: index0to7 position: a3dPoint</body>

<body package="CADSM-UI" selector="lightIndex:position:color:">lightIndex: index0to7 position: a3dPoint color: aColorValue</body>

<body package="CADSM-UI" selector="lightIndex:position:parallel:color:">lightIndex: index0to7 position: a3dPoint parallel: aBoolean color: aColorValue</body>

<body package="CADSM-UI" selector="lightIndex:position:parallel:color:alpha:">lightIndex: index0to7 position: a3dPoint parallel: aBoolean color: aColorValue alpha: aNumber</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>material</category>

<body package="CADSM-UI" selector="disableColorMaterial">disableColorMaterial</body>

<body package="CADSM-UI" selector="enableColorMaterial">enableColorMaterial</body>

<body package="CADSM-UI" selector="materialAmbient:">materialAmbient: aColorValue</body>

<body package="CADSM-UI" selector="materialAmbient:alpha:">materialAmbient: aColorValue alpha: aNumber</body>

<body package="CADSM-UI" selector="materialDiffuse:">materialDiffuse: aColorValue</body>

<body package="CADSM-UI" selector="materialDiffuse:alpha:">materialDiffuse: aColorValue alpha: aNumber</body>

<body package="CADSM-UI" selector="materialEmission:">materialEmission: aColorValue</body>

<body package="CADSM-UI" selector="materialEmission:alpha:">materialEmission: aColorValue alpha: aNumber</body>

<body package="CADSM-UI" selector="materialShininess:">materialShininess: aNumber</body>

<body package="CADSM-UI" selector="materialSpecular:">materialSpecular: aColorValue</body>

<body package="CADSM-UI" selector="materialSpecular:alpha:">materialSpecular: aColorValue alpha: aNumber</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>normalizing</category>

<body package="CADSM-UI" selector="disableNormalize">disableNormalize</body>

<body package="CADSM-UI" selector="enableNormalize">enableNormalize</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>shading</category>

<body package="CADSM-UI" selector="flatShading">flatShading</body>

<body package="CADSM-UI" selector="smoothShading">smoothShading</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>smoothing</category>

<body package="CADSM-UI" selector="disableLineSmooth">disableLineSmooth</body>

<body package="CADSM-UI" selector="disablePolygonSmooth">disablePolygonSmooth</body>

<body package="CADSM-UI" selector="enableLineSmooth">enableLineSmooth</body>

<body package="CADSM-UI" selector="enablePolygonSmooth">enablePolygonSmooth</body>

<body package="CADSM-UI" selector="lineSmoothDontCare">lineSmoothDontCare</body>

<body package="CADSM-UI" selector="lineSmoothNicest">lineSmoothNicest</body>

<body package="CADSM-UI" selector="polygonSmoothDontCare">polygonSmoothDontCare</body>

<body package="CADSM-UI" selector="polygonSmoothFastest">polygonSmoothFastest</body>

<body package="CADSM-UI" selector="polygonSmoothNicest">polygonSmoothNicest</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>stippling</category>

<body package="CADSM-UI" selector="enablePolygonStipple">enablePolygonStipple</body>

<body package="CADSM-UI" selector="polygonStipple:">polygonStipple: aJunOpenGLStipple</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>texture mapping</category>

<body package="CADSM-UI" selector="enableTexture2d">enableTexture2d</body>

<body package="CADSM-UI" selector="texture:">texture: aTexture</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>utilities</category>

<body package="CADSM-UI" selector="normalUnitVectorOfPoints:">normalUnitVectorOfPoints: anArrayOfPoints 
	"1,1,1 / 3 sqrt"

	^0.57735027955204d , 0.57735027955204d , 0.57735027955204d</body>

<body package="CADSM-UI" selector="normalVectorOfPoints:">normalVectorOfPoints: anArrayOfPoints 
	^1 , 1 , 1</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext</class-id> <category>private</category>

<body package="CADSM-UI" selector="maxID">maxID
	^OpenGLInterface GLuint baseType maxVal</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLPickingRenderingContext class</class-id> <category>instance creation</category>

<body package="CADSM-UI" selector="extent:">extent: aPoint 
	| medium |
	medium := OpenGLRetainedMedium extent: aPoint.
	^self on: medium</body>

<body package="CADSM-UI" selector="extent:bufferSize:">extent: aPoint bufferSize: anInteger 
	| pickingRenderingContext |
	pickingRenderingContext := self extent: aPoint.
	pickingRenderingContext selectionBufferSize: anInteger.
	^pickingRenderingContext</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLSolidRenderingContext</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="displayFaceUse:">displayFaceUse: aFaceUse 
	^self displayFaceUse: aFaceUse displayMode: OpenGLInterface GLU_FILL

	"	^self displayFaceUse: aFaceUse
		displayMode: OpenGLInterface GLU_OUTLINE_POLYGON"

	"	^self displayFaceUse: aFaceUse
		displayMode: OpenGLInterface GLU_OUTLINE_PATCH"</body>

<body package="CADSM-UI" selector="displayPolyface:">displayPolyface: crfpf 
	"JunOpenGL3dNonConvexPolygon does not have the last vertex repeated."

	| cVertex nonConvexPolygon normalVector |
	cVertex := Array new: crfpf size - 1.
	1 to: crfpf size - 1
		do: [:i | cVertex at: i put: (crfpf at: i) asJun3dPoint].
	nonConvexPolygon := JunOpenGL3dNonConvexPolygon vertexes: cVertex.
	normalVector := nonConvexPolygon normalVector.
	self activate: 
			[OpenGLInterface glBegin: OpenGLInterface GL_TRIANGLES.
			OpenGLInterface 
				glNormal3d: normalVector x asDouble
				with: normalVector y asDouble
				with: normalVector z asDouble.
			nonConvexPolygon triangles do: 
					[:triangle | 
					triangle do: 
							[:a3dPoint | 
							| a2dPoint |
							(textureCoordinateBlock notNil 
								and: [(a2dPoint := textureCoordinateBlock value: a3dPoint) notNil]) 
									ifTrue: 
										[OpenGLInterface glTexCoord2d: a2dPoint x asDouble with: a2dPoint y asDouble].
							OpenGLInterface 
								glVertex3d: a3dPoint x asDouble
								with: a3dPoint y asDouble
								with: a3dPoint z asDouble]].
			OpenGLInterface glEnd]</body>

<body package="CADSM-UI" selector="displayPolygon:">displayPolygon: aCollectionOfPoints 
	| normalVector |
"	self debugShow: (OpenGLInterface glEnable: OpenGLInterface GL_DEPTH_TEST).
	OpenGLInterface glDepthFunc: OpenGLInterface GL_ALWAYS."
	normalVector := self normalVectorOfPoints: aCollectionOfPoints.
	normalVector isNil ifTrue: [^nil].
	self displayPolygon: aCollectionOfPoints normalVector: normalVector.
"	self debugShow: OpenGLInterface glGetError"</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLWireframeRenderingContext</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="displayFaceUse:">displayFaceUse: aFaceUse 
	^self displayFaceUse: aFaceUse
		displayMode: OpenGLInterface GLU_OUTLINE_POLYGON</body>

<body package="CADSM-UI" selector="displayPolygon:">displayPolygon: aCollectionOfPoints 
	self displaySeeThroughWireframe: aCollectionOfPoints</body>
</methods>

<methods>
<class-id>CADSM.UI.OpenGLHiddenLineRenderingContext</class-id> <category>displaying</category>

<body package="CADSM-UI" selector="displayPolygon:">displayPolygon: aCollectionOfPoints 
	self displayHiddenLineRendering: aCollectionOfPoints</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUITreeNode</class-id> <category>accessing</category>

<body package="CADSM-UI" selector="addChild:">addChild: item 
	item notNil ifTrue: [children add: item asTreeNode]</body>

<body package="CADSM-UI" selector="addCollection:">addCollection: cItem 
	"Do not treat collection as a node."

	cItem notNil 
		ifTrue: 
			[children := Core.List new: cItem size.
			cItem do: [:item | children add: item asTreeNode].
			children 
				sortWith: [:node1 :node2 | node1 geoItem name &lt;= node2 geoItem name]]</body>

<body package="CADSM-UI" selector="addCollection:name:">addCollection: cItem name: string 
	"Treat collection as a node."

	| child |
	cItem notNil 
		ifTrue: 
			[child := CADSM.UI.CADSMUITreeNode new.
			child geoItem: cItem.
			child addCollection: cItem.
			child displayString: string.
			children add: child]</body>

<body package="CADSM-UI" selector="children">children
	^children isNil
		ifTrue: [children := Array new]
		ifFalse: [children]</body>

<body package="CADSM-UI" selector="children:">children: aCollection 
	children := aCollection</body>

<body package="CADSM-UI" selector="displayString">displayString
	^displayString</body>

<body package="CADSM-UI" selector="displayString:">displayString: string 
	
	[geoItem name: string.
	displayString := string]
		on: Core.MessageNotUnderstood
		do: 
			[:ex | 
			displayString isNil ifTrue: [displayString := string].
			ex return]</body>

<body package="CADSM-UI" selector="geoItem">geoItem
	^geoItem</body>

<body package="CADSM-UI" selector="geoItem:">geoItem: item 
	geoItem := item</body>

<body package="CADSM-UI" selector="inPlaceEdit:">inPlaceEdit: string 
	self displayString: string</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUITreeNode</class-id> <category>initialize-release</category>

<body package="CADSM-UI" selector="initialize">initialize
	children := Core.List new: 1</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUITreeNode</class-id> <category>copying</category>

<body package="CADSM-UI" selector="copyFrom:">copyFrom: node 
	| dictA dictB childB childA setA |
	geoItem == node geoItem
		ifTrue: 
			[children notNil
				ifTrue: 
					[dictA := Core.IdentityDictionary new: children size.
					children do: [:child | dictA at: child geoItem put: child].
					dictB := Core.IdentityDictionary new: node children size.
					node children do: [:child | dictB at: child geoItem put: child].
					children
						do: 
							[:child | 
							childB := dictB removeKey: child geoItem.
							childB notNil
								ifTrue: 
									[childA := dictA removeKey: child geoItem.
									childA copyFrom: childB]].
					setA := nil.
					dictA isEmpty
						ifFalse: 
							[setA isNil ifTrue: [setA := children asSet].
							dictA do: [:value | setA remove: value]].
					dictB isEmpty
						ifFalse: 
							[setA isNil ifTrue: [setA := children asSet].
							dictB do: [:value | setA add: value]].
					setA notNil
						ifTrue: 
							[children := setA asList.
							children sortWith: [:node1 :node2 | node1 displayString &lt;= node2 displayString]]].
			displayString := node displayString]
		ifFalse: 
			[geoItem := node geoItem.
			children := node children.
			displayString := node displayString]</body>
</methods>

<methods>
<class-id>CADSM.UI.CADSMUITreeNode</class-id> <category>comparing</category>

<body package="CADSM-UI" selector="=">= anObject 
	^self == anObject</body>
</methods>

<methods>
<class-id>CADSM.UI.RegistrationDialog class</class-id> <category>interface specs</category>

<body package="CADSM-UI" selector="windowSpec">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'CADSM Setup Dialog' 
			#min: #(#{Core.Point} 540 332 ) 
			#max: #(#{Core.Point} 540 332 ) 
			#bounds: #(#{Graphics.Rectangle} 490 404 1030 736 ) 
			#isEventDriven: true ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.TextEditorSpec} 
					#layout: #(#{Graphics.Rectangle} 27 14 513 150 ) 
					#name: #aTextEditorID 
					#model: #aTextEditor 
					#isReadOnly: true 
					#tabRequiresControl: true ) 
				#(#{UI.LabelSpec} 
					#properties: #(#{UI.PropertyListDictionary} #labelFromApplication false ) 
					#layout: #(#{Core.Point} 42 176 ) 
					#label: 'Full name' 
					#style: #default ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 42 228 ) 
					#name: #Label1 
					#label: 'Email address' 
					#style: #default ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.LayoutSizedOrigin} 150 0 171 0 350 31 ) 
					#model: #aFullName 
					#style: #default 
					#type: #string ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 150 223 500 254 ) 
					#model: #aEmail 
					#style: #default 
					#type: #string ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.LayoutSizedOrigin} 0 0.148148 0 0.831325 71 25 ) 
					#model: #accept 
					#label: 'Continue' 
					#style: #default 
					#defaultable: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.LayoutSizedOrigin} 0 0.437037 0 0.828313 71 25 ) 
					#model: #reset 
					#label: 'Reset' 
					#style: #default 
					#defaultable: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.LayoutSizedOrigin} 0 0.724074 0 0.831325 71 25 ) 
					#model: #cancel 
					#label: 'Exit' 
					#style: #default 
					#defaultable: true ) ) ) )</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor class</class-id> <category>interface specs</category>

<body package="CADSM-UI" selector="windowSpec">windowSpec
	"Tools.UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'CADSM' 
			#min: #(#{Core.Point} 40 20 ) 
			#bounds: #(#{Graphics.Rectangle} 390 308 1030 788 ) 
			#flags: 4 
			#menu: #menuBar 
			#isEventDriven: true ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.LayoutFrame} 0 0 -32 1 300 0 0 1 ) 
					#name: #selection 
					#isOpaque: true 
					#model: #selection 
					#isReadOnly: true ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 302 0 -32 1 0 1 0 1 ) 
					#name: #adButton 
					#flags: 0 
					#majorKey: #{StCAD.StDoc.AdButton} 
					#minorKey: #windowSpec 
					#clientKey: #adButton ) 
				#(#{UI.ArbitraryComponentSpec} 
					#layout: #(#{Graphics.LayoutFrame} 0 0.2 0 0 0 1 -33 1 ) 
					#name: #cadView 
					#flags: 11 
					#component: #cadView ) 
				#(#{UI.TreeViewSpec} 
					#layout: #(#{Graphics.LayoutFrame} 0 0 0 0 0 0.2 -33 1 ) 
					#name: #treeView 
					#flags: 15 
					#model: #treeView 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#focusInSelector: 
						#updateTreeModel: 
						#doubleClickSelector: 
						#doubleClick: ) 
					#menu: #menuTreeView 
					#useModifierKeys: true 
					#selectionType: #highlight 
					#displayStringSelector: #displayString 
					#inPlaceEditedSelector: 
					#inPlaceEdit: 
					#rootExpander: true ) ) ) )</body>
</methods>

<methods>
<class-id>CADSM.UI.Editor class</class-id> <category>resources</category>

<body package="CADSM-UI" selector="handleImage">handleImage
	"Tools.UIMaskEditor new openOnClass: self andSelector: #handleImage"

	&lt;resource: #image&gt;
	^CachedImage on: (Image extent: 5@5 depth: 1 bitsPerPixel: 1 palette: (Graphics.MappedPalette withColors: ((Core.Array new: 1) at: 1 put: Graphics.ColorValue black; yourself)) usingBits: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])</body>

<body package="CADSM-UI" selector="handleImage2">handleImage2
	"Tools.UIMaskEditor new openOnClass: self andSelector: #handleImage2"

	&lt;resource: #image&gt;
	^CachedImage on: (Image extent: 5@5 depth: 1 bitsPerPixel: 1 palette: CoveragePalette monoMaskPalette usingBits: #[248 0 0 0 248 0 0 0 248 0 0 0 248 0 0 0 248 0 0 0])</body>

<body package="CADSM-UI" selector="menuBar">menuBar
	"Tools.MenuEditor new openOnClass: self andSelector: #menuBar"

	&lt;resource: #menu&gt;
	^#(#{UI.Menu} #(
			#(#{UI.MenuItem} 
				#rawLabel: 'Explain' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Quick Test' 
							#value: #menuExplainQuickTest ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Quick Start' 
							#value: #menuExplainQuickStart ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Known Problems' 
							#value: #menuExplainKnownProblems ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Introduction' 
							#value: #menuExplainIntroduction ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Tree View' 
							#value: #menuExplainTreeView ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Usage' 
							#value: #menuExplainUsage ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'About' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'freeCAD' 
										#value: #menuExplainAboutfreeCAD ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'StCAD' 
										#value: #menuExplainAboutStCAD ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Patch' 
										#value: #menuExplainAboutPatch ) ) #(3 ) nil ) ) ) #(7 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'File' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#value: #menuFileExplain ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'New' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Assembly' 
										#value: #menuFileNewAssembly ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Part' 
										#enabled: false 
										#value: #menuFileNewPart 
										#hidden: true ) ) #(2 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Open' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Assembly' 
										#value: #menuFileOpenAssembly ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Part' 
										#enabled: false 
										#value: #menuFileOpenPart 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'MOSES *.ppo' 
										#value: #menuFileOpenMOSESppo ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Sebert *.dat' 
										#enabled: false 
										#value: #menuFileOpenSebertdat 
										#hidden: true ) ) #(4 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Save As' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Assembly' 
										#value: #menuFileSaveAsAssembly ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Part' 
										#value: #menuFileSaveAsPart ) ) #(2 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Save As Text' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Assembly' 
										#value: #menuFileSaveAsTextAssembly ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Part' 
										#enabled: false 
										#value: #menuFileSaveAsTextPart 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'PDMSReview' 
										#value: #menuFileSaveAsTextPDMSReview ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'POV-Ray' 
										#value: #menuFileSaveAsTextPOVRay 
										#submenu: #(#{UI.Menu} #(
												#(#{UI.MenuItem} 
													#rawLabel: 'Current State' 
													#value: #menuFileSaveAsTextPOVRayCurrent ) 
												#(#{UI.MenuItem} 
													#rawLabel: 'Time Series' 
													#value: #menuFileSaveAsTextPOVRaySeries ) ) #(2 ) nil ) ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'LMU Path' 
										#enabled: false 
										#value: #menuFileSaveAsTextLMUPath 
										#hidden: true ) ) #(5 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Properties' 
							#enabled: false 
							#value: #menuFileProperties 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Exit' 
							#value: #menuFileExit ) ) #(3 4 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Edit' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#value: #menuEditExplain ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Undo' 
							#value: #menuEditUndo ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Find' 
							#enabled: false 
							#value: #menuEditFind 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Copy' 
							#enabled: false 
							#value: #menuEditCopy 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Cut' 
							#value: #menuEditCut ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Paste' 
							#enabled: false 
							#value: #menuEditPaste 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Marker Size' 
							#value: #menuEditMarkerSize ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Notes' 
							#value: #menuEditNotes ) ) #(6 2 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'View' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#value: #menuViewExplain ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Y up' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'X right' 
										#value: #menuViewYupXright ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'X left' 
										#value: #menuViewYupXleft ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Z right' 
										#value: #menuViewYupZright ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Z left' 
										#value: #menuViewYupZleft ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad + + +' 
										#value: #menuViewYupQuadppp ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad - + +' 
										#value: #menuViewYupQuadmpp ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad - + -' 
										#value: #menuViewYupQuadmpm ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad + + -' 
										#value: #menuViewYupQuadppm ) ) #(8 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Z up' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'X right' 
										#value: #menuViewZupXright ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'X left' 
										#value: #menuViewZupXleft ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Y right' 
										#value: #menuViewZupYright ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Y left' 
										#value: #menuViewZupYleft ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad + + +' 
										#value: #menuViewZupQuadppp ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad + - +' 
										#value: #menuViewZupQuadpmp ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad - - +' 
										#value: #menuViewZupQuadmmp ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quad - + +' 
										#value: #menuViewZupQuadmpp ) ) #(8 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'X right Y up' 
							#enabled: false 
							#value: #menuViewXrightYup 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'X right Z down' 
							#enabled: false 
							#value: #menuViewXrightZdown 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Y up Z left' 
							#enabled: false 
							#value: #menuViewYupZleft 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Tilt Rotate Universe' 
							#value: #menuViewTiltRotateUniverse ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Zoom In' 
							#value: #menuViewZoomIn ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Zoom Out' 
							#value: #menuViewZoomOut ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Show' 
							#enabled: false 
							#value: #menuViewShow 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Transcript' 
							#value: #menuViewTranscript ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Notes' 
							#value: #menuViewNotes ) ) #(12 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Select' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#value: #menuSelectExplain ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Plane' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'x=X y=Y' 
										#value: #menuSelectPlaneXrightYup ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Rotate x' 
										#submenu: #(#{UI.Menu} #(
												#(#{UI.MenuItem} 
													#rawLabel: '90 deg' 
													#value: #menuSelectPlaneRotatex90 ) 
												#(#{UI.MenuItem} 
													#rawLabel: '180 deg' 
													#value: #menuSelectPlaneRotatex180 ) 
												#(#{UI.MenuItem} 
													#rawLabel: '270 deg' 
													#value: #menuSelectPlaneRotatex270 ) ) #(3 ) nil ) ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Rotate y' 
										#submenu: #(#{UI.Menu} #(
												#(#{UI.MenuItem} 
													#rawLabel: '90 deg' 
													#value: #menuSelectPlaneRotatey90 ) 
												#(#{UI.MenuItem} 
													#rawLabel: '180 deg' 
													#value: #menuSelectPlaneRotatey180 ) 
												#(#{UI.MenuItem} 
													#rawLabel: '270 deg' 
													#value: #menuSelectPlaneRotatey270 ) ) #(3 ) nil ) ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Rotate z' 
										#submenu: #(#{UI.Menu} #(
												#(#{UI.MenuItem} 
													#rawLabel: '90 deg' 
													#value: #menuSelectPlaneRotatez90 ) 
												#(#{UI.MenuItem} 
													#rawLabel: '180 deg' 
													#value: #menuSelectPlaneRotatez180 ) 
												#(#{UI.MenuItem} 
													#rawLabel: '270 deg' 
													#value: #menuSelectPlaneRotatez270 ) ) #(3 ) nil ) ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'x=X y=-Z' 
										#enabled: false 
										#value: #menuSelectPlaneXrightZdown 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'x=-Z y=Y' 
										#enabled: false 
										#value: #menuSelectPlaneYupZleft 
										#hidden: true ) ) #(6 ) nil ) ) ) #(2 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Insert' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#value: #menuInsertExplain ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Assembly' 
							#enabled: false 
							#hidden: true 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'New' 
										#value: #menuInsertAssemblyNew ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'File' 
										#value: #menuInsertAssemblyFile ) ) #(2 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Part' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'New' 
										#value: #menuInsertPartNew ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'File' 
										#value: #menuInsertPartFile ) ) #(2 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Sketch' 
							#value: #menuInsertSketch ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Feature' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Extrusion' 
										#value: #menuInsertFeatureExtrusion ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Cut' 
										#enabled: false 
										#value: #menuInsertFeatureCut 
										#hidden: true ) ) #(2 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Marker' 
							#value: #menuInsertMarker ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Others' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'MOSES Frame' 
										#value: #menuInsertMOSESFrame ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'PDMSReview Frame' 
										#value: #menuInsertPDMSFrame ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'POV-Ray Frame' 
										#enabled: false 
										#value: #menuInsertPOVRayFrame 
										#hidden: true ) ) #(3 ) nil ) ) ) #(6 1 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Draw' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#value: #menuDrawExplain ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Line' 
							#enabled: false 
							#value: #menuDrawLine 
							#hidden: true ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Rectangle' 
							#value: #menuDrawRectangle ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Circle' 
							#value: #menuDrawCircle ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Ellipse' 
							#value: #menuDrawEllipse ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Polyline' 
							#value: #menuDrawPolyline ) ) #(6 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Kinematic' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Joint' 
										#value: #menuKinematicExplainJoint ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Motion' 
										#value: #menuKinematicExplainMotion ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'KinematicIJ' 
										#value: #menuKinematicExplainKineIJ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Coupler' 
										#enabled: false 
										#value: #menuKinematicExplainCoupler 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Redundant Constraint' 
										#value: #menuKinematicExplainRedundantConstraint ) ) #(4 1 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Joint' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Constant VelocityZ' 
										#value: #menuJointConstantVelocityZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Coupler' 
										#enabled: false 
										#value: #menuJointCoupler 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Curve On Curve' 
										#value: #menuJointCurveOnCurve ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'CylindricalZ' 
										#value: #menuJointCylindricalZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Fixed' 
										#value: #menuJointFixed ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'No Rotation' 
										#value: #menuJointNoRotation ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'ParallelZ' 
										#value: #menuJointParallelZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'PerpendicularZ' 
										#value: #menuJointPerpendicularZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'PlanarXY' 
										#value: #menuJointPlanarXY ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Point In Curve' 
										#enabled: false 
										#value: #menuJointPointInCurve 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Point In LineZ' 
										#value: #menuJointPointInLineZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Point In PlaneXY' 
										#value: #menuJointPointInPlaneXY ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'RackX And PinionZ' 
										#value: #menuJointRackXAndPinionZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'RevoluteZ' 
										#value: #menuJointRevoluteZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'ScrewZ' 
										#value: #menuJointScrewZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Spherical' 
										#value: #menuJointSpherical ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'TranslationalZ' 
										#value: #menuJointTranslationalZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'UniversalZ' 
										#value: #menuJointUniversalZ ) ) #(18 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Motion' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'General' 
										#value: #menuMotionGeneral ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'RotationalZ' 
										#value: #menuMotionRotationalZ ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'TranslationalZ' 
										#value: #menuMotionTranslationalZ ) ) #(3 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'KinematicIJ' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Create' 
										#value: #menuKinematicKineIJCreate ) ) #(1 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Coupler' 
							#enabled: false 
							#value: #menuKinematicCoupler 
							#hidden: true ) ) #(5 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Dynamic' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Mass' 
										#value: #menuDynamicExplainMass ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'ForceTorque' 
										#value: #menuDynamicExplainForceTorque ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Gravity' 
										#value: #menuDynamicExplainGravity ) ) #(3 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'ForceTorque' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'General' 
										#value: #menuDynamicForceTorqueGeneral ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'In-Line' 
										#value: #menuDynamicForceTorqueInLine ) ) #(2 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Gravity' 
							#value: #menuDynamicGravity ) ) #(3 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Simulation' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Explain' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Initial Condition' 
										#value: #menuSimulationExplainIC ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Quasi Static' 
										#value: #menuSimulationExplainQuasiStatic ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Transient' 
										#value: #menuSimulationExplainTransient ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Stop' 
										#value: #menuSimulationExplainStop ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Animation' 
										#value: #menuSimulationExplainAnimation ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Plot' 
										#value: #menuSimulationExplainPlot ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Vector' 
										#enabled: false 
										#value: #menuSimulationExplainVector 
										#hidden: true ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'FreeBody' 
										#enabled: false 
										#value: #menuSimulationExplainFreeBody 
										#hidden: true ) ) #(8 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Initial Conditions' 
							#submenu: #(#{UI.Menu} #(
									#(#{UI.MenuItem} 
										#rawLabel: 'Previous Input State' 
										#value: #menuSimulationPreviousInputState ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Previous Assembled State' 
										#value: #menuSimulationPreviousAssembledState ) 
									#(#{UI.MenuItem} 
										#rawLabel: 'Zero All Velocities' 
										#value: #menuSimulationZeroAllVelocities ) ) #(3 ) nil ) ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'QuasiStatic' 
							#value: #menuSimulationQuasiStatic ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Transient' 
							#value: #menuSimulationDynamic ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Stop' 
							#value: #menuSimulationStop ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Animation' 
							#value: #menuSimulationAnimation ) ) #(1 1 3 1 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: 'Sponsor    ' 
				#submenu: #(#{UI.Menu} #(
						#(#{UI.MenuItem} 
							#rawLabel: 'Corporate' 
							#value: #menuSponsorCorporate ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Individual' 
							#value: #menuSponsorIndividual ) 
						#(#{UI.MenuItem} 
							#rawLabel: 'Ashlar-Vellum' 
							#enabled: false 
							#value: #menuSponsorAshlarVellum 
							#hidden: true ) ) #(3 ) nil ) ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''TiltRotate''' 
				#value: #menuViewTiltRotateUniverse ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''ZoomIn''' 
				#value: #menuViewZoomIn ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''ZoomOut''    ' 
				#value: #menuViewZoomOut ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''Solid''' 
				#value: #menuViewPresentationSolid ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''HideLine''' 
				#value: #menuViewPresentationHideLine ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''Wireframe''    ' 
				#value: #menuViewPresentationWireframe ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''Animation''' 
				#value: #menuSimulationAnimation ) 
			#(#{UI.MenuItem} 
				#rawLabel: '''Inspect''' 
				#value: #menuInspect ) ) #(19 ) nil ) decodeAsLiteralArray</body>

<body package="CADSM-UI" selector="menuTreeView">menuTreeView
	"MenuEditor new openOnClass: self andSelector: #menuTreeView"

	&lt;resource: #menu&gt;
	^#(#{UI.Menu} #(
			#(#{UI.MenuItem} 
				#rawLabel: 'Rename' 
				#value: #inplaceEdit ) ) #(1 ) nil ) decodeAsLiteralArray</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation class</class-id> <category>interface specs</category>

<body package="CADSM-UI" selector="windowSpec">windowSpec
	"UIPainter new openOnClass: self andSelector: #windowSpec"

	&lt;resource: #canvas&gt;
	^#(#{UI.FullSpec} 
		#window: 
		#(#{UI.WindowSpec} 
			#label: 'Animation                              Sponsor Logo' 
			#min: #(#{Core.Point} 438 155 ) 
			#max: #(#{Core.Point} 438 155 ) 
			#bounds: #(#{Graphics.Rectangle} 512 384 950 539 ) 
			#menu: #menuBar 
			#isEventDriven: true ) 
		#component: 
		#(#{UI.SpecCollection} 
			#collection: #(
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 16 58 ) 
					#name: #Label1 
					#label: 'Start' 
					#style: #default ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 16 82 ) 
					#name: #Label2 
					#label: 'End' 
					#style: #default ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 251 5 ) 
					#name: #Label3 
					#label: 'Time' 
					#style: #default ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 16 34 ) 
					#name: #Label4 
					#label: 'Current' 
					#style: #default ) 
				#(#{UI.LabelSpec} 
					#layout: #(#{Core.Point} 372 5 ) 
					#name: #Label5 
					#label: 'Speed' 
					#style: #default ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 77 34 139 59 ) 
					#name: #icurrentID 
					#colors: 
					#(#{UI.LookPreferences} 
						#setBackgroundColor: #(#{Graphics.ColorValue} #white ) ) 
					#model: #icurrent 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#requestFocusOutSelector: 
						#validateRange: 
						#requestValueChangeSelector: 
						#validateRange: ) 
					#alignment: #right 
					#style: #default 
					#type: #number 
					#formatString: '0' ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 77 58 139 83 ) 
					#name: #InputField1 
					#colors: 
					#(#{UI.LookPreferences} 
						#setBackgroundColor: #(#{Graphics.ColorValue} #white ) ) 
					#model: #istart 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#requestFocusOutSelector: 
						#validateRange: 
						#requestValueChangeSelector: 
						#validateRange: ) 
					#alignment: #right 
					#style: #default 
					#type: #number 
					#formatString: '0' ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 77 82 139 107 ) 
					#name: #InputField2 
					#colors: 
					#(#{UI.LookPreferences} 
						#setBackgroundColor: #(#{Graphics.ColorValue} #white ) ) 
					#model: #iend 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#requestFocusOutSelector: 
						#validateRange: 
						#requestValueChangeSelector: 
						#validateRange: ) 
					#alignment: #right 
					#style: #default 
					#type: #number 
					#formatString: '0' ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 139 34 288 59 ) 
					#name: #InputField3 
					#model: #tcurrent 
					#alignment: #right 
					#style: #default 
					#isReadOnly: true ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 139 58 288 83 ) 
					#name: #InputField4 
					#model: #tstart 
					#alignment: #right 
					#style: #default 
					#isReadOnly: true ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 139 82 288 107 ) 
					#name: #InputField5 
					#model: #tend 
					#alignment: #right 
					#style: #default 
					#isReadOnly: true ) 
				#(#{UI.InputFieldSpec} 
					#layout: #(#{Graphics.Rectangle} 359 33 421 58 ) 
					#name: #InputField6 
					#flags: 0 
					#model: #speed 
					#callbacksSpec: 
					#(#{UI.UIEventCallbackSubSpec} 
						#requestFocusOutSelector: 
						#validateSpeed: 
						#requestValueChangeSelector: 
						#validateSpeed: ) 
					#alignment: #right 
					#style: #default 
					#type: #number 
					#formatString: '0' ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 77 5 139 30 ) 
					#name: #ActionButton1 
					#model: #frameAction 
					#label: 'Frame' 
					#style: #default 
					#isDefault: false 
					#defaultable: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 297 34 359 59 ) 
					#name: #ActionButton2 
					#model: #play 
					#label: 'Play' 
					#style: #default 
					#isDefault: false 
					#defaultable: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 297 58 359 83 ) 
					#name: #ActionButton3 
					#model: #stop 
					#label: 'Stop' 
					#style: #default 
					#isDefault: false 
					#defaultable: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 297 82 359 107 ) 
					#name: #ActionButton4 
					#model: #step 
					#label: 'Step' 
					#style: #default 
					#isDefault: false 
					#defaultable: true ) 
				#(#{UI.ActionButtonSpec} 
					#layout: #(#{Graphics.Rectangle} 359 82 421 107 ) 
					#name: #ActionButton5 
					#model: #directionAction 
					#label: 'Direction' 
					#style: #default 
					#isDefault: false 
					#defaultable: true ) 
				#(#{UI.SubCanvasSpec} 
					#layout: #(#{Graphics.LayoutFrame} 0 0 -38 1 0 1 -6 1 ) 
					#name: #adButtonID 
					#flags: 0 
					#colors: 
					#(#{UI.LookPreferences} 
						#setBackgroundColor: #(#{Graphics.ColorValue} #black ) ) 
					#majorKey: #{StCAD.StDoc.AdButton} 
					#minorKey: #windowSpec 
					#clientKey: #adButton ) ) ) )</body>
</methods>

<methods>
<class-id>CADSM.UI.Animation class</class-id> <category>resources</category>

<body package="CADSM-UI" selector="directionMenu">directionMenu
	"MenuEditor new openOnClass: self andSelector: #directionMenu"

	&lt;resource: #menu&gt;
	^#(#Menu #(
			#(#MenuItem 
				#rawLabel: 'Forward' 
				#nameKey: #menuDirectionForwardID 
				#value: #menuDirectionForward 
				#indication: true ) 
			#(#MenuItem 
				#rawLabel: 'Backward' 
				#nameKey: #menuDirectionBackwardID 
				#value: #menuDirectionBackward 
				#indication: true ) ) #(2 ) nil ) decodeAsLiteralArray</body>

<body package="CADSM-UI" selector="frameMenu">frameMenu
	"MenuEditor new openOnClass: self andSelector: #frameMenu"

	&lt;resource: #menu&gt;
	^#(#Menu #(
			#(#MenuItem 
				#rawLabel: 'Input State' 
				#value: #menuFrameInputState ) 
			#(#MenuItem 
				#rawLabel: 'First' 
				#value: #menuFrameFirst ) 
			#(#MenuItem 
				#rawLabel: 'Last' 
				#value: #menuFrameLast ) ) #(3 ) nil ) decodeAsLiteralArray</body>
</methods>

<methods>
<class-id>CADSM.UI.Handle class</class-id> <category>resources</category>

<body package="CADSM-UI" selector="handleImage">handleImage
	"Tools.UIMaskEditor new openOnClass: self andSelector: #handleImage"

	&lt;resource: #image&gt;
	^(Image extent: 5@5 depth: 1 bitsPerPixel: 1 palette: (Graphics.MappedPalette withColors: ((Core.Array new: 1) at: 1 put: Graphics.ColorValue black; yourself)) usingBits: #[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])</body>

<body package="CADSM-UI" selector="handleImage2">handleImage2
	"Tools.UIMaskEditor new openOnClass: self andSelector: #handleImage2"

	&lt;resource: #image&gt;
	^(Image extent: 8@8 depth: 1 bitsPerPixel: 1 palette: MonoMappedPalette blackWhite usingBits: #[0 0 0 0 96 0 0 0 0 0 0 0 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0])</body>

<body package="CADSM-UI" selector="handleImage3">handleImage3
	"Tools.UIMaskEditor new openOnClass: self andSelector: #handleImage3"

	&lt;resource: #image&gt;
	^(Image extent: 5@5 depth: 1 bitsPerPixel: 1 palette: (Graphics.MappedPalette withColors: ((Core.Array new: 2) at: 1 put: Graphics.ColorValue black; at: 2 put: Graphics.ColorValue yellow; yourself)) usingBits: #[0 0 0 0 96 0 0 0 0 0 0 0 48 0 0 0 0 0 0 0])</body>
</methods>

<initialize>
<class-id>CADSM.UI.ASMTextParser</class-id>
</initialize>

<do-it>"Imported Classes:"</do-it>

<do-it>self error: 'Attempting to file-in parcel imports.  Choose terminate or close'</do-it>

<class>
<name>Object</name>
<environment>Core</environment>
<super></super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Kernel-Objects</category>
<attributes>
<package>Kernel-Objects</package>
</attributes>
</class>

<class>
<name>CADDrawingInterface</name>
<environment>StCAD</environment>
<super>Polymorphic.GFDrawingInterface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cadApp depthSortedGOsUnderCursor geoRootItem selectedGEOs worldFrame projectionFrame activeSketch mbdProcess </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CAD</category>
<attributes>
<package>xCAD</package>
</attributes>
</class>

<class>
<name>CADSMItem</name>
<environment>Smalltalk</environment>
<super>Core.Object</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Basic</category>
<attributes>
<package>CADSM</package>
</attributes>
</class>

<class>
<name>JunOpenGLRetainedMedium</name>
<environment>Jun</environment>
<super>Jun.JunOpenGLResource</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>medium extent </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Jun-OpenGL-Support</category>
<attributes>
<package>Jun-OpenGL-Support</package>
</attributes>
</class>

<class>
<name>ExternalLanguageParser</name>
<environment>Kernel</environment>
<super>Kernel.GeneralParser</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>AT-ParserCompiler</category>
<attributes>
<package>AT Parser Compiler</package>
</attributes>
</class>

<class>
<name>JunOpenGLRenderingContext</name>
<environment>Jun</environment>
<super>Jun.JunOpenGLResource</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>medium handle paint alpha lineWidth pointSize projection shading lightIndex lightStates nurbsSamplingTolerance presentation transformation texture textureCoordinateBlock textureCoordinateIndex depthMask lineStippleFactor lineStipplePattern polygonStipple lineSmooth polygonSmooth cullFace ambientLight lights materialAmbient materialDiffuse materialEmission materialShininess materialSpecular fogColor fogExpDensity fogExp2Density fogLinearDensity enableDisables viewport backgroundColor </inst-vars>
<class-inst-vars>enhancements </class-inst-vars>
<imports></imports>
<category>Jun-OpenGL-Support</category>
<attributes>
<package>Jun-OpenGL-Support</package>
</attributes>
</class>

<class>
<name>JunOpenGLDisplayController</name>
<environment>Jun</environment>
<super>Jun.JunAbstractControllerWithMenu</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>movementVector enableMovementProcess </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Jun-OpenGL-Display</category>
<attributes>
<package>Jun-OpenGL-Display</package>
</attributes>
</class>

<class>
<name>View</name>
<environment>UI</environment>
<super>Graphics.DependentPart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>controller properties </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Interface-Framework</category>
<attributes>
<package>Interface-Framework</package>
</attributes>
</class>

<class>
<name>ScrollingTracker</name>
<environment>UI</environment>
<super>UI.SelectionTracker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>process </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Interface-Events-Trackers</category>
<attributes>
<package>Interface-Events-Trackers</package>
</attributes>
</class>

<class>
<name>ApplicationModel</name>
<environment>UI</environment>
<super>UI.Model</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>builder uiSession eventHandlers </inst-vars>
<class-inst-vars>savedWindowInformation </class-inst-vars>
<imports></imports>
<category>UIBuilder-Framework</category>
<attributes>
<package>UIBuilder-Framework</package>
</attributes>
</class>

<class>
<name>SimpleDialog</name>
<environment>UI</environment>
<super>UI.ApplicationModel</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>close accept cancel preBuildBlock postBuildBlock postOpenBlock escapeIsCancel parentView </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>Interface-Dialogs</category>
<attributes>
<package>Interface-Dialogs</package>
</attributes>
</class>

</st-source>
