<?xml version="1.0"?>

<st-source>
<!-- 
Name: CADSM-Geo
HideSource: false
PackageName: CADSM-Geo
Parcel: #('cadsmgeo')
ParcelName: CADSM-Geo
PrerequisiteParcels: #(#('CADSM-Namespace' '') #('CADSM-Math' '') #('CADSM-Misc' '') #('xCADns' '') #('xMath' ''))
SaveSource: true
Version: 2
Date: 4:20:21 pm October 30, 2009
 -->
<time-stamp>From VisualWorks®, 7.5 of April 16, 2007 on October 30, 2009 at 4:20:21 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>CADSMGeoCombination</name>
<environment>CADSM.Geo</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-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoCombination</class-id>
<body>GeometricPair subclasses are utility objects to compute interactions between two geometrical elements.</body>
</comment>

<class>
<name>CADSMGeoPointArc</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCombination</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aCenter aRadius aStartAngle aEndAngle aPar bPoint bAngle aClosestPoint aRightDist aMinDist </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoThreePoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCombination</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>a1Point a2Point a3Point </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoPointLine</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCombination</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>a0 aDir aPar b0 aClosestPoint aRightDist aMinDist </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoLineGeneralArc</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCombination</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoLineArc</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoLineGeneralArc</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoLineLine</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCombination</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>a0 aDir aPar aClosestPoint b0 bDir bPar bClosestPoint tolParallel aMinDist tolDist aCrossPoint </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoLineLine</class-id>
<body>
	Find the minimum distance between two lines. 
	Line is a(ap) = a0 + ap*ad. 
	Line is b(bp) = b0 + bp*bd. 
	Minimize a(ap) - b(bp). 
	Therefore 
	ap = bd*(a0 - b0) ad*bd - ad*(a0 - b0) bd*bd / (ad*ad bd*bd - ad*bd ad*bd). 
	bp = bd*(a0 - b0) ad*ad - ad*(a0 - b0) bd*ad / (ad*ad bd*bd - ad*bd ad*bd). 
	</body>
</comment>

<class>
<name>CADSMGeoCartesianFrame</name>
<environment>CADSM.Geo</environment>
<super>CADSMAbstractCartesianFrame</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>rFfF aAFf rOfO aAOf </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id>
<body>Cartesian frame system.

Instance Variables:

refFrame	&lt;nil or GEOCartesianFrame&gt;	base frame of current frame.
rFfF	&lt;StMFullColumn&gt;	displacement from base frame origin to current frame origin in base frame components.
aAFf	&lt;StMFullMatrix&gt;	transformation matrix such that {IJK}F := [aAFf] {ijk}f.
rOfO	&lt;StMFullColumn&gt;	displacement from world frame origin to current frame origin in world frame components.
aAOf	&lt;StMFullMatrix&gt;	transformation matrix such that {IJK}O := [aAOf] {ijk}f.
dependentFrames	&lt;IdentitySet&gt;	set of dependent frames.
body	&lt;aObject&gt;	any object associated with the current frame.</body>
</comment>

<class>
<name>CADSMGeoAbsoluteFrame</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCartesianFrame</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoItem</name>
<environment>CADSM.Geo</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-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSphericalFrame</name>
<environment>CADSM.Geo</environment>
<super>CADSMAbstractSphericalFrame</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>r theta psi rFfF aAFf rOfO aAOf </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoOriginFrame</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCartesianFrame</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoOriginFrame</class-id>
<body>No relative displacement or rotation. Use for efficiency.</body>
</comment>

<class>
<name>CADSMGeoCylindricalFrame</name>
<environment>CADSM.Geo</environment>
<super>CADSMAbstractCylindricalFrame</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>r theta z rFfF aAFf rOfO aAOf </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSubItem</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cEventHandler aSup </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoGravity</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSubItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>gXYZ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Force</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoConstraintSet</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSubItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>name cConstraint </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRelativeConstraintSet</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoConstraintSet</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aMarkerI aMarkerJ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoRelativeConstraintSet</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCylSphJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>distanceIJ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoInLineJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSphericalJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoParallelAxesJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoTranslationalJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoGearJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>radiusI radiusJ aConstant </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoPointInLineJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoInLineJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoMotion</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoRelativeConstraintSet</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>xIJ yIJ zIJ phiIJ theIJ psiIJ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoTranslationalMotion</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoMotion</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRevoluteJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoGeneralMotion</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoMotion</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>rotOrder </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoAngleJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>theIzJz </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoKineIJ</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoRelativeConstraintSet</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRevCylJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>distanceIJ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoScrewJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>pitch aConstant </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRackPinJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>pitchRadius aConstant </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoAllowZRotation</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoMotion</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoFixedJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSpatialItem</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSubItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>name aRefFrame aBoundingBox </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id>
<body>SpatialItem 

Instance Variables:
	aRefFrame		&lt;CartesianFrame&gt;
	boundingBox	&lt;BoundingBox&gt;	in aRefFrame coordinates.
	name			&lt;Symbol&gt;
	aUI can used to store a UI object. It is stores in eventHandlers.

</body>
</comment>

<class>
<name>CADSMGeoGeometry</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>isSpatial </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCamera</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>left right top bottom near far shading presentation lineSmoothBoolean polygonSmoothBoolean cLighting </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id>
<body>

Instance Variables:
	cLighting	&lt;Collection of Lightings&gt;	These lightings are defined relative to the camera.
	distance	&lt;aNumber&gt;	Distance from lens to point of focus or eyepoint to sightpoint.
	far	&lt;Object&gt;	description of far
	height	&lt;Object&gt;	description of height
	lineSmoothBoolean	&lt;Object&gt;	description of lineSmoothBoolean
	near	&lt;Object&gt;	description of near
	polygonSmoothBoolean	&lt;Object&gt;	description of polygonSmoothBoolean
	presentation	&lt;Object&gt;	description of presentation
	shading	&lt;Object&gt;	description of shading
	viewFactor	&lt;Object&gt;	description of viewFactor

</body>
</comment>

<class>
<name>CADSMGeoAnyLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>isOn </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSingleLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoAnyLighting</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>color alpha </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSpotLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSingleLighting</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cutoffAngle </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoParallelCamera</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCamera</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoUniverse</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cCamera cLighting cAssembly </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoUniverse</class-id>
<body>Let Universe be the mediator.

Instance Variables:
	aAssembly	&lt;Assembly&gt;	description of aAssembly
	cCamera	&lt;Collection of Cameras&gt;	Remembered cameras. The first element is the active camera for arbitrary camera motion.
	cLighting	&lt;Collection of Lightings&gt;	These are lighting in space not fixed to cameras.

</body>
</comment>

<class>
<name>CADSMGeoArrayLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoAnyLighting</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cLighting </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoPerpendicularJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoPointLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSingleLighting</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCVCVJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>coeffRestitution </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoAnyPart</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoAnyPart</class-id>
<body>AnyPart 

Instance Variables:
	aMbD can used to store a MbD object. It is stores in eventHandlers.
	aFEM can used to store a FEM object. It is stores in eventHandlers.
	aCFD can used to store a CFD object. It is stores in eventHandlers.

</body>
</comment>

<class>
<name>CADSMGeoFusedPart</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoAnyPart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cPart </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoFusedPart</class-id>
<body>Collection of Parts that are stuck together to behave like a single Part. Fixed joints create FusedParts.

Instance Variables:
	cPart	&lt;Object&gt;	description of cPart

</body>
</comment>

<class>
<name>CADSMGeoPart</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoAnyPart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cRefGeo aMassMarker aNMT </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoAssembly</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoAnyPart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cAnyPart cConstraintSet cForceTorque cField cVariable aSimData aTimeSeries </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id>
<body>An assembly has one fixed part at the origin to accept markers. Other parts are not fixed.

Instance Variables:
	aSimData	&lt;Object&gt;	description of aSimData
	aTimeSeries	&lt;Object&gt;	description of aTimeSeries
	cAnyPart	&lt;Object&gt;	description of cAnyPart
	cConstraintSet	&lt;Object&gt;	description of cConstraintSet
	cField	&lt;Object&gt;	description of cField
	cForceTorque	&lt;Object&gt;	description of cForceTorque
	cNote	&lt;Object&gt;	description of cNote
	cVariable	&lt;Object&gt;	description of cVariable

</body>
</comment>

<class>
<name>CADSMGeoFixedPart</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoPart</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSphSphJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>distanceIJ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoGeometry</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSweep</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aCurve trajectory </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoSweep</class-id>
<body>aCurve can be a full 3D curve. Refer to 'The NURBS Book'.
aSweep aRefFrame and trajectory aRefFrame are made coincident with the aCurve aRefFrame.

Instance Variables:
	aCurve	&lt;Object&gt;	description of aCurve
	trajectory	&lt;Object&gt;	description of trajectory

</body>
</comment>

<class>
<name>CADSMGeoPlane</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aRectSurface </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoNurbsSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>ccPoint ccWeight cuKnot cvKnot uDegree vDegree umin umax vmin vmax tolSingularity cSingularity </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface</class-id>
<body>See comment for NurbsCurve.</body>
</comment>

<class>
<name>CADSMGeoPerspectiveCamera</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCamera</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>distance height viewFactor </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCylindricalJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoInLineJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRectSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoRectSurface</class-id>
<body>aBoundingBox stores extent of RectSurface. z should be zero. u and v values are from 0 to 1.</body>
</comment>

<class>
<name>CADSMGeoMarker</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoMassMarker</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoMarker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>mass aJppx aJppy aJppz density </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCurveMarker</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoMarker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>s </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoAmbientLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSingleLighting</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSurfaceMarker</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurveMarker</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoUniversalJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCurve</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoGeometry</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoLine</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>rfstartf rfendf dsdu </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCurve2D</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoEllipse</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve2D</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>xRadius yRadius </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoEllipticArc</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoEllipse</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>theStart theEnd </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCurve3D</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>isPlanar </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoNurbsCurve</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve3D</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cPoint cWeight cWPoint cuKnot uDegree umin umax </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id>
<body>Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
cPoint is the collection of control points (p0, p1, ..., pn)
cWeight is the collection of weights (w0, w1, ..., wn)
cUKnot is the collection of knots (u0, u1, ..., um)
The degree of the spline is p.
m + 1 = (n + 1) + (p + 1).
In words: nKnot - nPoint = degree + 1.
The end values of the knots are identical for (p+ 1) values.
(a, a, ..., a, up+1, up+2, ..., um-p-2, um-p-1, b, ...,b, b)

B-Spline basis functions
Ni,j := basis function for span i of degree j.
i = 0, ..., m-1
j = 0, ..., p


Instance Variables:
	cPoint	&lt;Object&gt;	description of cPoint
	cUKnot	&lt;Object&gt;	description of cUKnot
	cWeight	&lt;Object&gt;	description of cWeight

</body>
</comment>

<class>
<name>CADSMGeoPolyline</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve3D</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>crfpointf isClosed </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoEquationCurve</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve3D</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>rfpfEqn </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCircle</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoEllipse</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRotationalMotion</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoMotion</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRectangle</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoCurve2D</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>xLength yLength </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSurfaceOfRevolution</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurface</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aCurve </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoSurfaceOfRevolution</class-id>
<body>Revolve about z axis.
u is equator. trajectory is a circle.
v is in positive direction. curve is defined in xz plane.</body>
</comment>

<class>
<name>CADSMGeoSphericalSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurfaceOfRevolution</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoSphericalSurface</class-id>
<body>aCurve is a meridian arc from the south pole (-z) to the north pole (+z).</body>
</comment>

<class>
<name>CADSMGeoToroidalSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurfaceOfRevolution</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoCylindricalSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurfaceOfRevolution</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoCylindricalSurface</class-id>
<body>aCurve is a line from
(radius, zStart)
to
(radius, zEnd)

zStart &lt; zEnd
</body>
</comment>

<class>
<name>CADSMGeoRefGeo</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSpatialItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cMarker </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoRefGeo</class-id>
<body>RefGeo is for part to store markers for MbD.

</body>
</comment>

<class>
<name>CADSMGeoRefPoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoRefGeo</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRefCurve</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoRefGeo</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>rfEqnf </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoRefSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoRefCurve</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoConstantVelocityJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoParallelLighting</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSingleLighting</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoParallelLighting</class-id>
<body>Light will point along the z direction.</body>
</comment>

<class>
<name>CADSMGeoTime</name>
<environment>CADSM.Geo</environment>
<super>StCAD.StGeo.GEOFunction</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoConicalSurface</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSurfaceOfRevolution</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>radius semi_angle </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Basic</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<comment>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id>
<body>aCurve is a line from
(xStart, zStart)
to
(xEnd, zEnd)

zStart &lt; zEnd
xStart := radius + (zStart * semi_angle tan)</body>
</comment>

<class>
<name>CADSMGeoForceTorque</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSubItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>name aMarkerI aMarkerJ </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Force</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoForceTorqueInLine</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoForceTorque</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>tensionFunc twistFunc </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Force</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoForceTorqueGeneral</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoForceTorque</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>aMarkerK aFIeKe aTIeKe </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Force</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoInPlaneJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>offset </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoPointInPlaneJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoInPlaneJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoLineInPlaneJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoInPlaneJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoPlanarJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoInPlaneJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoNoRotationJoint</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoJoint</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo-Constraint</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<class>
<name>CADSMGeoSupItem</name>
<environment>CADSM.Geo</environment>
<super>CADSM.Geo.CADSMGeoSubItem</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars>cSub </inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>CADSM-Geo</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</class>

<shared-variable>
<name>TwoPi</name>
<environment>CADSM.Geo.CADSMGeoEllipse</environment>
<private>false</private>
<constant>false</constant>
<category>all</category>
<initializer>-1.0d arcCos * 2.0d</initializer>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</shared-variable>

<shared-variable>
<name>TwoPi</name>
<environment>CADSM.Geo.CADSMGeoCombination</environment>
<private>false</private>
<constant>false</constant>
<category>constants</category>
<initializer>Double twoPi</initializer>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</shared-variable>

<shared-variable>
<name>HalfPi</name>
<environment>CADSM.Geo.CADSMGeoCombination</environment>
<private>false</private>
<constant>false</constant>
<category>constants</category>
<initializer>Double halfPi</initializer>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</shared-variable>

<shared-variable>
<name>Pi</name>
<environment>CADSM.Geo.CADSMGeoCombination</environment>
<private>false</private>
<constant>false</constant>
<category>constants</category>
<initializer>Double pi</initializer>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</shared-variable>

<shared-variable>
<name>CcBinomial</name>
<environment>CADSM.Geo.CADSMGeoNurbsCurve</environment>
<private>false</private>
<constant>false</constant>
<category>As yet unclassified</category>
<attributes>
<package>CADSM-Geo</package>
</attributes>
</shared-variable>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointArc</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aCenter:aRadius:aStartAngle:aEndAngle:bPoint:">aCenter: aFullColumn aRadius: aDouble aStartAngle: argStartAngle aEndAngle: argEndAngle bPoint: bFullColumn 
	aCenter := aFullColumn.
	aRadius := aDouble.
	aStartAngle := argStartAngle.
	aEndAngle := argEndAngle.
	bPoint := bFullColumn</body>

<body package="CADSM-Geo" selector="aClosestPoint">aClosestPoint
	^aClosestPoint</body>

<body package="CADSM-Geo" selector="aMinDist">aMinDist
	^aMinDist</body>

<body package="CADSM-Geo" selector="aPar">aPar
	^aPar</body>

<body package="CADSM-Geo" selector="aRightDist">aRightDist
	^aRightDist</body>

<body package="CADSM-Geo" selector="bAngle">bAngle
	^bAngle</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointArc</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="calc">calc
	| delta dist a1Par a2Par |
	aEndAngle &gt; aStartAngle ifFalse: [self error: 'Check this.'].
	delta := bPoint - aCenter.
	dist := delta length.
	bAngle := Double arcTan0to2piY: (delta at: 2) overX: (delta at: 1).
	a1Par := (bAngle - aStartAngle) / (aEndAngle - aStartAngle).
	a2Par := (bAngle + TwoPi - aStartAngle) / (aEndAngle - aStartAngle).
	aPar := (a1Par - 0.5d) abs &lt; (a2Par - 0.5d) abs 
				ifTrue: [a1Par]
				ifFalse: [a2Par].
	aRightDist := dist - aRadius.
	aMinDist := aRightDist abs.
	aClosestPoint := aCenter + (CADSMCoordinateFrame 
						xyz_r: aRadius
						theta: bAngle
						z: 0.0d)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointArc class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="aCenter:aRadius:aStartAngle:aEndAngle:bPoint:">aCenter: aCenter aRadius: aRadius aStartAngle: aStartAngle aEndAngle: aEndAngle bPoint: bPoint 
	^(super new)
		aCenter: aCenter
			aRadius: aRadius
			aStartAngle: aStartAngle
			aEndAngle: aEndAngle
			bPoint: bPoint;
		calc;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoThreePoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="a1Point">a1Point
	^a1Point</body>

<body package="CADSM-Geo" selector="a1Point:">a1Point: anObject
	a1Point := anObject</body>

<body package="CADSM-Geo" selector="a2Point">a2Point
	^a2Point</body>

<body package="CADSM-Geo" selector="a2Point:">a2Point: anObject
	a2Point := anObject</body>

<body package="CADSM-Geo" selector="a3Point">a3Point
	^a3Point</body>

<body package="CADSM-Geo" selector="a3Point:">a3Point: anObject
	a3Point := anObject</body>

<body package="CADSM-Geo" selector="center_r_angleS_angleE">center_r_angleS_angleE
	"Answer radius and center of circle passing through three points."

	| x1 y1 x2 y2 x3 y3 a b c d e f g cx cy r inf angleS angleE posDir aStartTangent temp |
	x1 := a1Point at: 1.
	y1 := a1Point at: 2.
	x2 := a2Point at: 1.
	y2 := a2Point at: 2.
	x3 := a3Point at: 1.
	y3 := a3Point at: 2.
	a := x2 - x1.
	b := y2 - y1.
	c := x3 - x1.
	d := y3 - y1.
	e := a * (x1 + x2) + (b * (y1 + y2)).
	f := c * (x1 + x3) + (d * (y1 + y3)).
	g := 2 * (a * (y3 - y2) - (b * (x3 - x2))).
	g abs &gt; 0.0d 
		ifTrue: 
			[cx := (d * e - (b * f)) / g.
			cy := (a * f - (c * e)) / g.
			r := ((x1 - cx raisedTo: 2) + (y1 - cy raisedTo: 2)) sqrt]
		ifFalse: 
			[inf := 1.0d100.
			cx := cy := r := inf].
	angleS := Double arcTan0to2piY: y1 - cy overX: x1 - cx.
	angleE := Double arcTan0to2piY: y3 - cy overX: x3 - cx.
	posDir := (a2Point - a1Point) normalizeSelf.
	aStartTangent := StMFullColumn 
				with: angleS negated sin
				with: angleS cos
				with: 0.0d.
	(posDir dot: aStartTangent) positive 
		ifFalse: 
			[temp := angleS.
			angleS := angleE.
			angleE := temp].
	angleE &gt; angleS ifFalse: [angleE := angleE + Double twoPi].
	^Array 
		with: (StMFullColumn 
				with: cx
				with: cy
				with: 0.0d)
		with: r
		with: angleS
		with: angleE</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoThreePoint class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="a1Point:a2Point:a3Point:">a1Point: a1Point a2Point: a2Point a3Point: a3Point 
	^(self new)
		a1Point: a1Point;
		a2Point: a2Point;
		a3Point: a3Point;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointLine</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="calc">calc
	| aDirSSq aLength bDir |
	aDirSSq := aDir sumOfSquares.
	aLength := aDirSSq sqrt.
	bDir := b0 - a0.
	aPar := (bDir dot: aDir) / aDirSSq.
	aClosestPoint := a0 plusFullColumn: aDir times: aPar.
	aRightDist := ((bDir cross: aDir) at: 3) / aLength.
	aMinDist := aRightDist abs</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointLine</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="a0">a0
	^a0</body>

<body package="CADSM-Geo" selector="a0:aDir:b0:">a0: aFullColumn aDir: aaFullColumn b0: bFullColumn 
	a0 := aFullColumn.
	aDir := aaFullColumn.
	b0 := bFullColumn</body>

<body package="CADSM-Geo" selector="aClosestPoint">aClosestPoint
	^aClosestPoint</body>

<body package="CADSM-Geo" selector="aDir">aDir
	^aDir</body>

<body package="CADSM-Geo" selector="aMinDist">aMinDist
	^aMinDist</body>

<body package="CADSM-Geo" selector="aPar">aPar
	^aPar</body>

<body package="CADSM-Geo" selector="aRightDist">aRightDist
	^aRightDist</body>

<body package="CADSM-Geo" selector="b0">b0
	^b0</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointLine class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="a0:aDir:b0:">a0: a0 aDir: aDir b0: b0 
	^(super new)
		a0: a0
			aDir: aDir
			b0: b0;
		calc;
		yourself</body>

<body package="CADSM-Geo" selector="aStartPoint:aEndPoint:bPoint:">aStartPoint: aStartPoint aEndPoint: aEndPoint bPoint: bPoint 
	^self 
		a0: aStartPoint
		aDir: aEndPoint - aStartPoint
		b0: bPoint</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointLine class</class-id> <category>examples</category>

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

	| aStartPoint aEndPoint bPoint answer |
	aStartPoint := StMFullColumn 
				with: 1.0d
				with: 0.0d
				with: 1.0d.
	aEndPoint := StMFullColumn 
				with: 1.0d
				with: 1.0d
				with: 1.0d.
	bPoint := StMFullColumn 
				with: 1.0d
				with: 1.5d
				with: 1.0d.
	answer := self 
				aStartPoint: aStartPoint
				aEndPoint: aEndPoint
				bPoint: bPoint.
	answer inspect</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLineLine</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="a0">a0
	^a0</body>

<body package="CADSM-Geo" selector="a0:aDir:b0:bDir:tolParallel:tolDist:">a0: aFullColumn aDir: aaFullColumn b0: bFullColumn bDir: bbFullColumn tolParallel: aDouble tolDist: aaDouble 
	a0 := aFullColumn.
	aDir := aaFullColumn.
	b0 := bFullColumn.
	bDir := bbFullColumn.
	tolParallel := aDouble.
	tolDist := aaDouble</body>

<body package="CADSM-Geo" selector="aClosestPoint">aClosestPoint
	^aClosestPoint</body>

<body package="CADSM-Geo" selector="aCrossPoint">aCrossPoint
	^aCrossPoint</body>

<body package="CADSM-Geo" selector="aDir">aDir
	^aDir</body>

<body package="CADSM-Geo" selector="aMinDist">aMinDist
	^aMinDist</body>

<body package="CADSM-Geo" selector="aPar">aPar
	^aPar</body>

<body package="CADSM-Geo" selector="b0">b0
	^b0</body>

<body package="CADSM-Geo" selector="bClosestPoint">bClosestPoint
	^bClosestPoint</body>

<body package="CADSM-Geo" selector="bDir">bDir
	^bDir</body>

<body package="CADSM-Geo" selector="bPar">bPar
	^bPar</body>

<body package="CADSM-Geo" selector="tolParallel">tolParallel
	^tolParallel</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLineLine</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="calc">calc
	"See class comments."

	| a0mb0 adsq bdsq adbd ada0mb0 bda0mb0 denominator |
	a0mb0 := a0 - b0.
	adsq := aDir sumOfSquares.
	bdsq := bDir sumOfSquares.
	adbd := aDir dot: bDir.
	ada0mb0 := aDir dot: a0mb0.
	bda0mb0 := bDir dot: a0mb0.
	denominator := adsq * bdsq - (adbd * adbd).
	1.0d - ((aDir normalized dot: bDir normalized) raisedTo: 2) &gt; tolParallel 
		ifTrue: 
			[aPar := (bda0mb0 * adbd - (ada0mb0 * bdsq)) / denominator.
			bPar := (bda0mb0 * adsq - (ada0mb0 * adbd)) / denominator.
			aClosestPoint := a0 plus: aDir times: aPar.
			bClosestPoint := b0 plus: bDir times: bPar.
			aMinDist := (aClosestPoint minusFullColumn: bClosestPoint) length.
			aCrossPoint := aMinDist &lt; tolDist 
						ifTrue: [(aClosestPoint plusFullColumn: bClosestPoint) times: 0.5d]]
		ifFalse: ['Lines are parallel.']</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLineLine class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="a0:aDir:b0:bDir:tolParallel:tolDist:">a0: a3DPoint aDir: aDir b0: b3DPoint bDir: bDir tolParallel: tolParallel tolDist: tolDist 
	^(super new)
		a0: a3DPoint
			aDir: aDir
			b0: b3DPoint
			bDir: bDir
			tolParallel: tolParallel
			tolDist: tolDist;
		calc;
		yourself</body>

<body package="CADSM-Geo" selector="aStartPoint:aEndPoint:bStartPoint:bEndPoint:tolParallel:tolDist:">aStartPoint: aStartPoint aEndPoint: aEndPoint bStartPoint: bStartPoint bEndPoint: bEndPoint tolParallel: tolParallel tolDist: tolDist 
	^self 
		a0: aStartPoint
		aDir: aEndPoint - aStartPoint
		b0: bStartPoint
		bDir: bEndPoint - bStartPoint
		tolParallel: tolParallel
		tolDist: tolDist</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aAFf">aAFf
	^aAFf</body>

<body package="CADSM-Geo" selector="aAFf:">aAFf: aA 
	aAFf := aA.
	self changed</body>

<body package="CADSM-Geo" selector="aAFfforF:">aAFfforF: aFrame 
	^self == aFrame 
		ifTrue: [StCAD.StMath.StMFullMatrix identity: 3]
		ifFalse: 
			[| newSup aaAFf |
			newSup := aSup.
			aaAFf := aAFf.
			[newSup == aFrame] whileFalse: 
					[aaAFf := aaAFf timesFullMatrix: newSup aAFf.
					newSup := newSup aSup].
			aaAFf]</body>

<body package="CADSM-Geo" selector="aAfO">aAfO
	^self aAOf transpose</body>

<body package="CADSM-Geo" selector="aAOF">aAOF
	^aSup aAOf</body>

<body package="CADSM-Geo" selector="aAOf">aAOf
	^aAOf ifNil: 
			[aAOf := aSup ifNil: [aAFf] ifNotNil: [aSup aAOf timesFullMatrix: aAFf]]</body>

<body package="CADSM-Geo" selector="addDependentFrame:">addDependentFrame: aFrame 
	cSub add: aFrame</body>

<body package="CADSM-Geo" selector="addMarkersIn:">addMarkersIn: set 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="alpOfO">alpOfO
	^(self triggerEvent: #getalpOfO) ifNil: 
			[| answer |
			answer := StMFullColumn zero: 3.
			self alpOfO: answer.
			answer]</body>

<body package="CADSM-Geo" selector="alpOfO:">alpOfO: alpOfO 
	self removeActionsForEvent: #getalpOfO.
	alpOfO ifNotNil: 
			[self 
				when: #getalpOfO
				ask: alpOfO
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aMFf">aMFf
	| aAFf1 aAFf2 aAFf3 answer |
	aAFf1 := aAFf at: 1.
	aAFf2 := aAFf at: 2.
	aAFf3 := aAFf at: 3.
	answer := Jun3dTransformation basicNew.
	answer
		setA: (aAFf1 at: 1);
		setB: (aAFf2 at: 1);
		setC: (aAFf3 at: 1);
		setP: 0.0d.
	answer
		setD: (aAFf1 at: 2);
		setE: (aAFf2 at: 2);
		setF: (aAFf3 at: 2);
		setQ: 0.0d.
	answer
		setG: (aAFf1 at: 3);
		setH: (aAFf2 at: 3);
		setI: (aAFf3 at: 3);
		setR: 0.0d.
	answer
		setL: (rFfF at: 1);
		setM: (rFfF at: 2);
		setN: (rFfF at: 3);
		setS: 1.0d.
	^answer</body>

<body package="CADSM-Geo" selector="aMFfT">aMFfT
	| aAFf1 aAFf2 aAFf3 answer |
	aAFf1 := aAFf at: 1.
	aAFf2 := aAFf at: 2.
	aAFf3 := aAFf at: 3.
	answer := Jun3dTransformation basicNew.
	answer
		setA: (aAFf1 at: 1);
		setB: (aAFf1 at: 2);
		setC: (aAFf1 at: 3);
		setP: 0.0d.
	answer
		setD: (aAFf2 at: 1);
		setE: (aAFf2 at: 2);
		setF: (aAFf2 at: 3);
		setQ: 0.0d.
	answer
		setG: (aAFf3 at: 1);
		setH: (aAFf3 at: 2);
		setI: (aAFf3 at: 3);
		setR: 0.0d.
	answer
		setL: (rFfF at: 1);
		setM: (rFfF at: 2);
		setN: (rFfF at: 3);
		setS: 1.0d.
	^answer</body>

<body package="CADSM-Geo" selector="aOfO">aOfO
	^(self triggerEvent: #getaOfO) ifNil: 
			[| answer |
			answer := StMFullColumn zero: 3.
			self aOfO: answer.
			answer]</body>

<body package="CADSM-Geo" selector="aOfO:">aOfO: aOfO 
	self removeActionsForEvent: #getaOfO.
	aOfO ifNotNil: 
			[self 
				when: #getaOfO
				ask: aOfO
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="body">body
	^body</body>

<body package="CADSM-Geo" selector="body:">body: aObject 
	body := aObject</body>

<body package="CADSM-Geo" selector="crFpFfromcrfpf:forF:">crFpFfromcrfpf: crfpf forF: aFrame 
	| arFfF aaAFf |
	^self == aFrame 
		ifTrue: [crfpf copy]
		ifFalse: 
			[arFfF := aSup rFpFfromrfpf: rFfF forF: aFrame.
			aaAFf := self aAFfforF: aFrame.
			crfpf collect: [:arfpf | arFfF + (aaAFf timesFullColumn: arfpf)]]</body>

<body package="CADSM-Geo" selector="crfpffromcrOpO:">crfpffromcrOpO: crOpO 
	| aAfO arOfO |
	aAfO := self aAfO.
	arOfO := self rOfO.
	^crOpO collect: [:arOpO | aAfO timesFullColumn: arOpO - arOfO]</body>

<body package="CADSM-Geo" selector="fixedAtRef">fixedAtRef
	rFfF := (StMFullColumn zero: 3).
	aAFf := (StMFullMatrix identity: 3).
	self changed</body>

<body package="CADSM-Geo" selector="interface">interface
	^aSup interface</body>

<body package="CADSM-Geo" selector="isFace">isFace
	^false</body>

<body package="CADSM-Geo" selector="menu">menu
	^nil</body>

<body package="CADSM-Geo" selector="omeOfO">omeOfO
	^(self triggerEvent: #getomeOfO) ifNil: 
			[| answer |
			answer := StMFullColumn zero: 3.
			self omeOfO: answer.
			answer]</body>

<body package="CADSM-Geo" selector="omeOfO:">omeOfO: omeOfO 
	self removeActionsForEvent: #getomeOfO.
	omeOfO ifNotNil: 
			[self 
				when: #getomeOfO
				ask: omeOfO
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="positionMemento">positionMemento
	| aMemento |
	aMemento := Polymorphic.GFMemento originator: self.
	aMemento addActionSelector: #rFfF:aAFf:
		arguments: (Array with: rFfF copy with: aAFf copy).
	^aMemento</body>

<body package="CADSM-Geo" selector="quietlyrFfF:aAFf:">quietlyrFfF: rFpF aAFf: aAFp 
	"Must be used from the root on down."
	"Then the root must perform changed."

	rFfF := rFpF.
	aAFf := aAFp.
	rOfO := nil.
	aAOf := nil</body>

<body package="CADSM-Geo" selector="quietlyrOfO:aAOf:">quietlyrOfO: rOpO aAOf: aAOp 
	"Must be used from the root on down."
	"Then the root must perform changed."

	rFfF := aSup rfpffromrOpO: rOpO.
	aAFf := aSup aAOf transpose timesFullMatrix: aAOp.
	rOfO := rOpO.
	aAOf := aAOp</body>

<body package="CADSM-Geo" selector="quietlyvOfO:omeOfO:">quietlyvOfO: vOpO omeOfO: omeOfO 
	self vOfO: vOpO.
	self omeOfO: omeOfO</body>

<body package="CADSM-Geo" selector="rDbodycenterPx">rDbodycenterPx
	^self interface projectionFrame rDpPxfromrOpO: body rOcenterO</body>

<body package="CADSM-Geo" selector="rDoriginPx">rDoriginPx
	^self interface projectionFrame rDpPxfromrOpO: self rOfO</body>

<body package="CADSM-Geo" selector="rDpPxfromrfpf:">rDpPxfromrfpf: rfpf 
	^self interface projectionFrame rDpPxfromrOpO: (self rOpOfromrfpf: rfpf)</body>

<body package="CADSM-Geo" selector="refFrame">refFrame
	^aSup</body>

<body package="CADSM-Geo" selector="refFrame:">refFrame: aFrame 
	self setRefFrame: aFrame.
	self changed</body>

<body package="CADSM-Geo" selector="refFrame:rFfF:aAFf:">refFrame: aFrame rFfF: r aAFf: aA 
	self setRefFrame: aFrame.
	rFfF := r.
	aAFf := aA.
	self changed</body>

<body package="CADSM-Geo" selector="refFrame:rFfF:xPoint:yPoint:">refFrame: aFrame rFfF: origin xPoint: xPoint yPoint: yPoint 
	| aA |
	aA := StMFullMatrix
				rotationMatrixFromOrigin: origin
				xPoint: xPoint
				yPoint: yPoint.
	self
		refFrame: aFrame
		rFfF: origin
		aAFf: aA</body>

<body package="CADSM-Geo" selector="refFrame:rFfF:xPoint:zPoint:">refFrame: aFrame rFfF: origin xPoint: xPoint zPoint: zPoint 
	| aA |
	aA := StMFullMatrix
				rotationMatrixFromOrigin: origin
				xPoint: xPoint
				zPoint: zPoint.
	self
		refFrame: aFrame
		rFfF: origin
		aAFf: aA</body>

<body package="CADSM-Geo" selector="refFrame:rFfF:zPoint:xPoint:">refFrame: aFrame rFfF: origin zPoint: zPoint xPoint: xPoint 
	| aA |
	aA := StMFullMatrix
				rotationMatrixFromOrigin: origin
				zPoint: zPoint
				xPoint: xPoint.
	self
		refFrame: aFrame
		rFfF: origin
		aAFf: aA</body>

<body package="CADSM-Geo" selector="removeDependentFrame:">removeDependentFrame: frame 
	^cSub remove: frame ifAbsent: [nil]</body>

<body package="CADSM-Geo" selector="rFfF">rFfF
	^rFfF</body>

<body package="CADSM-Geo" selector="rFfF:">rFfF: col 
	rFfF := col.
	self changed</body>

<body package="CADSM-Geo" selector="rFfF:aAFf:">rFfF: r aAFf: aA 
	rFfF := r.
	aAFf := aA.
	self changed</body>

<body package="CADSM-Geo" selector="rFfF:xPoint:yPoint:">rFfF: origin xPoint: xPoint yPoint: yPoint 
	| aA |
	aA := StMFullMatrix 
				rotationMatrixFromOrigin: origin
				xPoint: xPoint
				yPoint: yPoint.
	self rFfF: origin aAFf: aA</body>

<body package="CADSM-Geo" selector="rFfF:xPoint:zPoint:">rFfF: origin xPoint: xPoint zPoint: zPoint 
	| aA |
	aA := StMFullMatrix 
				rotationMatrixFromOrigin: origin
				xPoint: xPoint
				zPoint: zPoint.
	self rFfF: origin aAFf: aA</body>

<body package="CADSM-Geo" selector="rFfF:zPoint:xPoint:">rFfF: origin zPoint: zPoint xPoint: xPoint 
	| aA |
	aA := StMFullMatrix 
				rotationMatrixFromOrigin: origin
				zPoint: zPoint
				xPoint: xPoint.
	self rFfF: origin aAFf: aA</body>

<body package="CADSM-Geo" selector="rFpFfromrfpf:">rFpFfromrfpf: rfpf 
	^rFfF plusFullColumn: (aAFf timesFullColumn: rfpf)</body>

<body package="CADSM-Geo" selector="rfpffromrFpF:">rfpffromrFpF: rFpF 
	^aAFf transpose timesFullColumn: rFpF - rFfF</body>

<body package="CADSM-Geo" selector="rFpFfromrfpf:forF:">rFpFfromrfpf: rfpf forF: aFrame 
	| rFpF |
	^self == aFrame 
		ifTrue: [rfpf]
		ifFalse: 
			[rFpF := self rFpFfromrfpf: rfpf.
			aSup rFpFfromrfpf: rFpF forF: aFrame]</body>

<body package="CADSM-Geo" selector="rFpFfromrOpO:">rFpFfromrOpO: rOpO 
	^self refFrame rfpffromrOpO: rOpO</body>

<body package="CADSM-Geo" selector="rfpffromrOpO:">rfpffromrOpO: rOpO 
	^self aAOf transpose timesFullColumn: rOpO - self rOfO</body>

<body package="CADSM-Geo" selector="rOfO">rOfO
	^rOfO ifNil: 
			[rOfO := aSup ifNil: [rFfF]
						ifNotNil: [aSup rOfO + (aSup aAOf timesFullColumn: rFfF)]]</body>

<body package="CADSM-Geo" selector="rOpOfromrfpf:">rOpOfromrfpf: rfpf 
	^self rOfO + (self aAOf timesFullColumn: rfpf)</body>

<body package="CADSM-Geo" selector="setRefFrame:">setRefFrame: aFrame 
	"Receiver must be dependent on only one refFrame."

	aSup notNil ifTrue: [aSup removeDependentFrame: self].
	aSup := aFrame.
	aSup notNil ifTrue: [aSup addDependentFrame: self]</body>

<body package="CADSM-Geo" selector="storeMemento:for:">storeMemento: aMemento for: anObject 
	aSup notNil ifTrue: [aSup storeMemento: aMemento for: anObject]</body>

<body package="CADSM-Geo" selector="translateSelfBy:">translateSelfBy: delta 
	self rFfF: self rFfF + delta</body>

<body package="CADSM-Geo" selector="trigAFf:">trigAFf: aA 
	aAFf := aA.
	self changed</body>

<body package="CADSM-Geo" selector="trigrefFrame:">trigrefFrame: aFrame 
	self setRefFrame: aFrame.
	self changed</body>

<body package="CADSM-Geo" selector="trigrFfF:">trigrFfF: col 
	rFfF := col.
	self changed</body>

<body package="CADSM-Geo" selector="unitx">unitx
	^StMFullColumn
		with: 1.0d
		with: 0.0d
		with: 0.0d</body>

<body package="CADSM-Geo" selector="unity">unity
	^StMFullColumn
		with: 0.0d
		with: 1.0d
		with: 0.0d</body>

<body package="CADSM-Geo" selector="unitz">unitz
	^StMFullColumn
		with: 0.0d
		with: 0.0d
		with: 1.0d</body>

<body package="CADSM-Geo" selector="vOfO">vOfO
	^(self triggerEvent: #getvOfO) ifNil: 
			[| answer |
			answer := StMFullColumn zero: 3.
			self vOfO: answer.
			answer]</body>

<body package="CADSM-Geo" selector="vOfO:">vOfO: vOfO 
	self removeActionsForEvent: #getvOfO.
	vOfO ifNotNil: [self
			when: #getvOfO
			ask: vOfO
			perform: #yourself]</body>

<body package="CADSM-Geo" selector="xyplaneCoeffs">xyplaneCoeffs</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="cut">cut
	aSup removeSub: self.
	super cut</body>

<body package="CADSM-Geo" selector="release">release
	"release self."

	aSup removeSub: self.
	aSup := nil.
	body notNil
		ifTrue: 
			[body releaseRefFrame.
			body := nil].
	super release</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aSup addSub: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>change</category>

<body package="CADSM-Geo" selector="changed">changed
	rOfO := nil.
	aAOf := nil.
	cSub do: [:aSub | aSub changed]</body>

<body package="CADSM-Geo" selector="conditionA">conditionA
	aAFf := StMFullMatrix 
				rotationMatrixFromOrigin: (StMFullColumn  zero: 3)
				zPoint: (aAFf column: 3)
				xPoint: (aAFf column: 1).
	cSub do: [:dependentFrame | dependentFrame conditionA]</body>

<body package="CADSM-Geo" selector="quietlyChanged">quietlyChanged
	self changed</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>copy</category>

<body package="CADSM-Geo" selector="copyrFfFandAFfFrom:">copyrFfFandAFfFrom: frame 
	rFfF := frame rFfF copy.
	aAFf := frame aAFf copy.
	self changed</body>

<body package="CADSM-Geo" selector="frozenCopy">frozenCopy
	"Used in handle tracking."

	| answer |
	answer := self shallowCopy.
	answer copyrFfFandAFfFrom: self.
	^answer</body>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	rFfF := rFfF copy.
	aAFf := aAFf copy.
	rOfO := nil.
	aAOf := nil</body>

<body package="CADSM-Geo" selector="preSave">preSave
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="axis:dotFrame:axis:">axis: i dotFrame: frame axis: j 
	^(self aAOf column: i)
		dot: (frame aAOf column: j)</body>

<body package="CADSM-Geo" selector="calc">calc
	self privateCalc.
	cSub do: [:aSub | aSub calc]</body>

<body package="CADSM-Geo" selector="calcAll">calcAll
	self calc.
	cSub do: [:aSub | aSub calcAll]</body>

<body package="CADSM-Geo" selector="dataAxesIntersectLine:axisLength:tolerance:">dataAxesIntersectLine: geoLine axisLength: length tolerance: tol 
	"
	Find the minimum distance to any axis. 
	General formula: 
	Line is P(t) = P0 + tv. 
	Line is Q(u) = Q0 + uw. 
	Minimize P(t) - Q(u). 
	Therefore 
	t = w*(P0 - Q0) v*w - v*(P0 - Q0) w*w / (v*v w*w - v*w v*w). 
	u = w*(P0 - Q0) v*v - v*(P0 - Q0) w*v / (v*v w*w - v*w v*w). 
	
	For x axis, P0 = (0,0,0), v = (1,0,0). 
	t = w*(- Q0) w1 - (- Q01) w*w / (w*w - w1w1) = Q01 w*w - w*Q0 w1 / (w*w - w1w1). 
	u = w*(- Q0) - (- Q01) w1 / (w*w - w1w1) = Q01 w1 - w*Q0 / (w*w - w1w1). 
	For y axis, P0 = (0,0,0), v = (0,1,0). 
	For z axis, P0 = (0,0,0), v = (0,0,1). 
	"

	| rfstartf rfendf q0 w wdotw i q0i wi wwmwiwi t u qIntsec minVector minDist wdotq0 |
	rfstartf := self rfpffromrOpO: geoLine rOstartO.
	rfendf := self rfpffromrOpO: geoLine rOendO.
	q0 := rfstartf.
	w := rfendf - rfstartf.
	wdotw := w sumOfSquares.
	wdotq0 := w dot: q0.
	i := 0.
	
	[i := i + 1.
	i &lt;= 3]
		whileTrue: 
			[q0i := q0 at: i.
			wi := w at: i.
			wwmwiwi := wdotw - (wi * wi).
			wwmwiwi &gt; StMMachineAccuracy OfDoubleTimesFour
				ifTrue: 
					[t := q0i * wdotw - (wdotq0 * wi) / wwmwiwi.
					u := q0i * wi - wdotq0 / wwmwiwi.
					qIntsec := q0 + (w times: u).
					minVector := qIntsec copy at: i minusNumber: t.
					minDist := minVector length.
					minDist &lt;= tol ifTrue: [^Array
							with: true
							with: i
							with: t
							with: u]]].
	^Array with: false</body>

<body package="CADSM-Geo" selector="dataXYPlaneIntersectLine:">dataXYPlaneIntersectLine: geoLine 
	"
	Find the intesection of the line on the xy plane. 
	General formula: 
	Plane is (x - P) dot v = 0. 
	Line is Q(t) = Q + tw. 
	Substitute x = Q(t) gives (Q + tw - P) dot v = 0. 
	Therefore 
	t = (P - Q) dot v / (w dot v). 
	Intersection point is at 
	Q + ((P - Q) dot v / (w dot v)) w. 
	
	For xy plane P = (0,0,0), v = (0,0,1). 
	"

	| rfstartf rfendf lineVector parameter rfIntsecf distStartIntsec |
	rfstartf := self rfpffromrOpO: geoLine rOstartO.
	rfendf := self rfpffromrOpO: geoLine rOendO.
	lineVector := rfendf - rfstartf.
	parameter := 0.0d - (rfstartf at: 3) / (lineVector at: 3).
	rfIntsecf := rfstartf plus: lineVector times: parameter.
	distStartIntsec := parameter * lineVector length.
	^Array
		with: parameter
		with: rfIntsecf
		with: distStartIntsec</body>

<body package="CADSM-Geo" selector="distXYPlaneIntersectLine:">distXYPlaneIntersectLine: geoLine 
	| data |
	data := self dataXYPlaneIntersectLine: geoLine.
	^data at: 3</body>

<body package="CADSM-Geo" selector="privateCalc">privateCalc
	"Calculate all dependent instance variables."

	| rOFO aAOF |
	aSup isNil 
		ifTrue: 
			[rOfO := rFfF.
			aAOf := aAFf]
		ifFalse: 
			[rOFO := aSup rOfO.
			aAOF := aSup aAOf.
			rOfO := rOFO + (aAOF timesFullColumn: rFfF).
			aAOf := aAOF timesFullMatrix: aAFf]</body>

<body package="CADSM-Geo" selector="removeFramesBetweenSelfAnd:">removeFramesBetweenSelfAnd: aFrame 
	| newrFfF newAFf |
	newrFfF := aFrame rfpffromrOpO: self rOfO.
	newAFf := aFrame aAOf transpose timesFullMatrix: self aAOf.
	self
		refFrame: aFrame
		rFfF: newrFfF
		aAFf: newAFf</body>

<body package="CADSM-Geo" selector="removeIntermediateFrame:">removeIntermediateFrame: aFrame 
	| aboveFrame middleFrame belowFrame newrFfF newAFf |
	aboveFrame := self.
	
	[middleFrame := aboveFrame refFrame.
	middleFrame ~~ aFrame and: [middleFrame isInterface not]]
		whileTrue: [aboveFrame := middleFrame].
	middleFrame == aFrame
		ifTrue: 
			[belowFrame := middleFrame refFrame.
			newrFfF := middleFrame rFpFfromrfpf: aboveFrame rFfF.
			newAFf := middleFrame aAFf timesFullMatrix: aboveFrame aAFf.
			aboveFrame
				refFrame: belowFrame
				rFfF: newrFfF
				aAFf: newAFf]</body>

<body package="CADSM-Geo" selector="rotateAt_axisF:theta:">rotateAt_axisF: axisF theta: theta 
	"Right hand rotation about axisF thru o."

	self 
		rotateAt_rFpvF: rFfF
		axisF: axisF
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateAt_axisf:theta:">rotateAt_axisf: axisf theta: theta 
	"Right hand rotation about axisf thru o."

	self 
		rotateAt_rFpvF: rFfF
		axisf: axisf
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateAt_rFpvF:axisF:theta:">rotateAt_rFpvF: rFpvF axisF: axisF theta: theta 
	"Right hand rotation about axisF thru rFpvF."

	| eulerParameter aAthe |
	eulerParameter := StMEulerParameters withAxis: axisF theta: theta.
	aAthe := eulerParameter aA.
	rFfF := rFpvF + (aAthe timesFullColumn: rFfF - rFpvF).
	aAFf := aAthe timesFullMatrix: aAFf.
	self changed</body>

<body package="CADSM-Geo" selector="rotateAt_rFpvF:axisf:theta:">rotateAt_rFpvF: rFpvF axisf: axisf theta: theta 
	"Right hand rotation about axisf thru rFpvF."

	self 
		rotateAt_rFpvF: rFpvF
		axisF: (aAFf timesFullColumn: axisf)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateAt_rfpvf:axisF:theta:">rotateAt_rfpvf: rfpvf axisF: axisF theta: theta 
	"Right hand rotation about axisF thru rfpvf."

	self 
		rotateAt_rFpvF: (self rFpFfromrfpf: rfpvf)
		axisF: axisF
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateAt_rfpvf:axisf:theta:">rotateAt_rfpvf: rfpvf axisf: axisf theta: theta 
	"Right hand rotation about axisf thru rfpvf."

	self 
		rotateAt_rFpvF: (self rFpFfromrfpf: rfpvf)
		axisF: (aAFf timesFullColumn: axisf)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateX:">rotateX: theta 
	self rotateAt_axisF: (StMFullColumn 
				with: 1.0d
				with: 0.0d
				with: 0.0d)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotatex:">rotatex: theta 
	self rotateAt_axisf: (StMFullColumn 
				with: 1.0d
				with: 0.0d
				with: 0.0d)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateY:">rotateY: theta 
	self rotateAt_axisF: (StMFullColumn 
				with: 0.0d
				with: 1.0d
				with: 0.0d)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotatey:">rotatey: theta 
	self rotateAt_axisf: (StMFullColumn 
				with: 0.0d
				with: 1.0d
				with: 0.0d)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotateZ:">rotateZ: theta 
	self rotateAt_axisF: (StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: 1.0d)
		theta: theta</body>

<body package="CADSM-Geo" selector="rotatez:">rotatez: theta 
	self rotateAt_axisf: (StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: 1.0d)
		theta: theta</body>

<body package="CADSM-Geo" selector="xyPlaneIntersectLine:">xyPlaneIntersectLine: geoLine 
	"
	Find the intesection of the line on the xy plane. 
	General formula: 
	Plane is (x - P) dot v = 0. 
	Line is Q(t) = Q + tw. 
	Substitute x = Q(t) gives (Q + tw - P) dot v = 0. 
	Therefore 
	t = (P - Q) dot v / (w dot v). 
	Intersection point is at 
	Q + ((P - Q) dot v / (w dot v)) w. 
	
	For xy plane P = (0,0,0), v = (0,0,1). 
	"

	| rfstartf rfendf lineVector denominator |
	rfstartf := self rfpffromrOpO: geoLine rOstartO.
	rfendf := self rfpffromrOpO: geoLine rOendO.
	lineVector := rfendf - rfstartf.
	denominator := lineVector at: 3.
	denominator abs &gt; 0.1d 
		ifTrue: [^rfstartf minus: lineVector times: (rfstartf at: 3) / denominator]
		ifFalse: 
			[Dialog 
				warn: 'It is not possible to locate a point \in a plane viewing it on edge.' 
						withCRs.
			StCAD.StGeo.NearParallelIntersectionError raiseSignal]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isAssembly">isAssembly
	^false</body>

<body package="CADSM-Geo" selector="isInterface">isInterface
	^false</body>

<body package="CADSM-Geo" selector="isPart">isPart
	^false</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="logString:">logString: string 
	aSup logString: string</body>

<body package="CADSM-Geo" selector="printOn:">printOn: aStream 
	| title |
	title := self class name.
	aStream 
		nextPutAll: ((title at: 1) isVowel ifTrue: ['an '] ifFalse: ['a ']).
	aStream print: self class.
	aStream nextPutAll: ' on '.
	aStream print: body.
	aStream
		cr;
		print: rFfF.
	aStream
		cr;
		print: aAFf</body>

<body package="CADSM-Geo" selector="printVerboseOn:">printVerboseOn: aStream 
	aStream
		nextPutAll: 'rFfF = ';
		print: rFfF;
		cr;
		nextPutAll: 'aAFf = ';
		print: (aAFf at: 1);
		cr;
		print: (aAFf at: 2);
		cr;
		print: (aAFf at: 3)</body>

<body package="CADSM-Geo" selector="store2DOn:level:">store2DOn: aStream level: level 
	aStream tabToLevel: level; nextPutAll: 'Position2D'; cr.
	aStream tabToLevel: level; tab; nextPutAll: (rFfF at: 1) printForExport; tab; nextPutAll: (rFfF at: 2) printForExport; cr.
	aStream tabToLevel: level; nextPutAll: 'Angle'; cr.
	aStream tabToLevel: level; tab; nextPutAll: (aAFf bryantAngles at: 3) printForExport; cr</body>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	aStream
		storeLevel: level
		title: 'Position3D'
		object: rFfF.
	aStream
		storeLevel: level
		title: 'RotationMatrix'
		object: aAFf</body>

<body package="CADSM-Geo" selector="storePOVOn:level1:">storePOVOn: aStream level1: level 
	| array |
	array := StCAD.StGeo.GEOEulerAngleszyx fromA: aAFf.
	array := array 
				collect: [:angle | angle radiansToDegrees asFloat printString].
	aStream storePOVLevel: level
		title: ('rotate %&lt;&lt;3s&gt;,&lt;2s&gt;,&lt;1s&gt;&gt;' expandMacrosWithArguments: array).
	array := rFfF collect: [:disp | disp asFloat printString].
	aStream storePOVLevel: level
		title: ('translate %&lt;&lt;1s&gt;,&lt;2s&gt;,&lt;3s&gt;&gt;' expandMacrosWithArguments: array)</body>

<body package="CADSM-Geo" selector="storeVelocityOn:level:">storeVelocityOn: aStream level: level 
	aStream
		storeLevel: level
		title: 'Velocity3D'
		object: (self vOfO notNil
				ifTrue: [self vOfO]
				ifFalse: [(StMFullColumn zero: 3)]).
	aStream
		storeLevel: level
		title: 'Omega3D'
		object: (self omeOfO notNil
				ifTrue: [self omeOfO]
				ifFalse: [(StMFullColumn zero: 3)])</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="rFpFfromrfpf2D:">rFpFfromrfpf2D: rfpf 
	"rFfF + (aAFf timesFullColumn: rfpf)"

	| u v |
	u := (rFfF at: 1) + ((aAFf at: 1 and: 1) * (rfpf at: 1) 
						+ ((aAFf at: 1 and: 2) * (rfpf at: 2))).
	v := (rFfF at: 2) + ((aAFf at: 2 and: 1) * (rfpf at: 1) 
						+ ((aAFf at: 2 and: 2) * (rfpf at: 2))).
	^u yd: v</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="refFrame:rFfF:aAFf:">refFrame: frame rFfF: r aAFf: aA 
	^self new
		refFrame: frame
		rFfF: r
		aAFf: aA</body>

<body package="CADSM-Geo" selector="refFrame:rFfF:xPoint:zPoint:">refFrame: aFrame rFfF: origin xPoint: xPoint zPoint: zPoint 
	^self new
		refFrame: aFrame
		rFfF: origin
		xPoint: xPoint
		zPoint: zPoint</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame class</class-id> <category>triggering events</category>

<body package="CADSM-Geo" selector="constructEventsTriggered">constructEventsTriggered
	^(super constructEventsTriggered)
		add: #getvOfO;
		add: #getomeOfO;
		add: #getaOfO;
		add: #getalpOfO;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCartesianFrame class</class-id> <category>utilities</category>

<body package="CADSM-Geo" selector="r_theta_z_xyz:">r_theta_z_xyz: xyz 
	| x y z |
	x := xyz at: 1.
	y := xyz at: 2.
	z := xyz at: 3.
	^StMArray 
		with: (x * x + (y * y)) sqrt
		with: (Double arcTan0to2piY: y overX: x)
		with: z</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAbsoluteFrame</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="axisLength">axisLength
	^1.0d</body>

<body package="CADSM-Geo" selector="boundingBox">boundingBox
	| axisLength |
	axisLength := self axisLength.
	^CADSMMiscBoundingBox origin: (StMFullColumn zero: 3)
		corner: (StMFullColumn 
				with: axisLength
				with: axisLength
				with: axisLength)</body>

<body package="CADSM-Geo" selector="fixedAtRef">fixedAtRef
	super fixedAtRef.
	rOfO := (StCAD.StMath.StMFullColumn zero: 3).
	aAOf := (StCAD.StMath.StMFullMatrix identity: 3)</body>

<body package="CADSM-Geo" selector="lineWidth">lineWidth
	^(self triggerEvent: #getlineWidth) ifNil: 
			[| answer |
			answer := 1.
			self lineWidth: answer.
			answer]</body>

<body package="CADSM-Geo" selector="lineWidth:">lineWidth: lineWidth 
	self removeActionsForEvent: #getlineWidth.
	lineWidth ifNotNil: 
			[self 
				when: #getlineWidth
				ask: lineWidth
				perform: #yourself]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAbsoluteFrame</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	self fixedAtRef</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAbsoluteFrame</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="renderOn:">renderOn: aRenderingContext 
	| pt000 pt100 pt010 pt001 |
	aRenderingContext 
		pushName: self name
		transformation: nil
		while: 
			[pt000 := 0 , 0 , 0.
			pt100 := 1 , 0 , 0.
			pt010 := 0 , 1 , 0.
			pt001 := 0 , 0 , 1.
			aRenderingContext lineWidth: self lineWidth.
			aRenderingContext paint: ColorValue red.
			aRenderingContext displayLine: (Array with: pt000 with: pt100).
			aRenderingContext paint: ColorValue green.
			aRenderingContext displayLine: (Array with: pt000 with: pt010).
			aRenderingContext paint: ColorValue blue.
			aRenderingContext displayLine: (Array with: pt000 with: pt001)]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoOriginFrame</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	self fixedAtRef</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCylindricalFrame class</class-id> <category>utilities</category>

<body package="CADSM-Geo" selector="xyz_r:theta:z:">xyz_r: r theta: theta z: z 
	^StMFullColumn 
		with: r * theta cos
		with: r * theta sin
		with: z</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSubItem</class-id> <category>private event table</category>

<body package="CADSM-Geo" selector="myEventTable">myEventTable
	^cEventHandler</body>

<body package="CADSM-Geo" selector="myEventTable:">myEventTable: anEventTable 
	cEventHandler := anEventTable</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSubItem</class-id> <category>change</category>

<body package="CADSM-Geo" selector="changed">changed
	self triggerEvent: #changed</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSubItem</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aMbDClass">aMbDClass
	^self class aMbDClass</body>

<body package="CADSM-Geo" selector="aMbDObject">aMbDObject
	^(self triggerEvent: #aMbDObject) ifNil: 
			[self createMbD.
			self triggerEvent: #aMbDObject]</body>

<body package="CADSM-Geo" selector="aMbDObject:">aMbDObject: aMbDObject 
	self removeActionsForEvent: #aMbDObject.
	aMbDObject ifNotNil: 
			[self 
				when: #aMbDObject
				ask: aMbDObject
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aMbDUnits">aMbDUnits
	^aSup ifNotNil: [aSup aMbDUnits]</body>

<body package="CADSM-Geo" selector="aMediator">aMediator
	^aSup ifNotNil: [aSup aMediator]</body>

<body package="CADSM-Geo" selector="asTreeNode">asTreeNode
	| answer |
	answer := CADSM.UI.CADSMUITreeNode new.
	answer geoItem: self.
	answer displayString: self name.
	^answer</body>

<body package="CADSM-Geo" selector="aSup">aSup
	^aSup</body>

<body package="CADSM-Geo" selector="aSup:">aSup: anObject
	aSup := anObject</body>

<body package="CADSM-Geo" selector="cDiscontinuity:">cDiscontinuity: cDiscontinuity 
	self removeActionsForEvent: #cDiscontinuity.
	cDiscontinuity notNil 
		ifTrue: 
			[self 
				when: #cDiscontinuity
				ask: cDiscontinuity
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="dataSeries">dataSeries
	| answer |
	answer := self triggerEvent: #getDataSeries.
	answer isNil 
		ifTrue: 
			[answer := OrderedCollection new.
			self dataSeries: answer].
	^answer</body>

<body package="CADSM-Geo" selector="dataSeries:">dataSeries: dataSeries 
	self removeActionsForEvent: #getDataSeries.
	dataSeries notNil ifTrue: [self
			when: #getDataSeries
			ask: dataSeries
			perform: #yourself]</body>

<body package="CADSM-Geo" selector="deleteMbD">deleteMbD
	self mbdObject: nil</body>

<body package="CADSM-Geo" selector="discontinuities:">discontinuities: discontinuities 
	self cDiscontinuity: discontinuities</body>

<body package="CADSM-Geo" selector="fullName">fullName
	| stream |
	stream := WriteStream on: (String new: 256).
	self fullpath do: [:node | (node respondsTo: #name)
			ifTrue: [node name isString
					ifTrue: 
						[stream nextPut: $/.
						stream nextPutAll: node name]]].
	^stream contents asSymbol</body>

<body package="CADSM-Geo" selector="fullpath">fullpath
	| fullpath |
	fullpath := aSup isNil 
				ifTrue: [OrderedCollection new]
				ifFalse: [aSup fullpath].
	fullpath add: self.
	^fullpath</body>

<body package="CADSM-Geo" selector="geoTime">geoTime
	^aSup ifNotNil: [aSup geoTime]</body>

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

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^self class mbdClass</body>

<body package="CADSM-Geo" selector="mbdObject">mbdObject
	^self aMbDObject</body>

<body package="CADSM-Geo" selector="mbdObject:">mbdObject: mbdObject 
	^self aMbDObject: mbdObject</body>

<body package="CADSM-Geo" selector="notes:">notes: notes 
	self removeActionsForEvent: #getNotes.
	notes notNil 
		ifTrue: 
			[self 
				when: #getNotes
				ask: notes
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="removeSup">removeSup
	aSup ifNotNil: [:aaSup | aaSup removeSub: self]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSubItem</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isAssembly">isAssembly
	^false</body>

<body package="CADSM-Geo" selector="isJoint">isJoint
	^false</body>

<body package="CADSM-Geo" selector="isMotion">isMotion
	^false</body>

<body package="CADSM-Geo" selector="isUniverse">isUniverse
	^false</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSubItem</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	cEventHandler := nil.
	aSup := nil</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGravity</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="asTreeNode">asTreeNode
	| answer |
	answer := super asTreeNode.
	answer displayString: 'Gravity'.
	^answer</body>

<body package="CADSM-Geo" selector="gX:gY:gZ:">gX: gX gY: gY gZ: gZ 
	""

	gXYZ := StMFullColumn new: 3.
	gXYZ at: 1 put: gX.
	gXYZ at: 2 put: gY.
	gXYZ at: 3 put: gZ</body>

<body package="CADSM-Geo" selector="gXYZ">gXYZ
	^gXYZ</body>

<body package="CADSM-Geo" selector="gXYZ:">gXYZ: col 
	gXYZ := col</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGravity</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| aMbDGravity |
	aMbDGravity := CADSMMbDGravity new.
	aMbDGravity gXYZ: gXYZ / self aMbDUnits acceleration.
	self aMbDObject: aMbDGravity.
	aSup aMbDObject aGravity: aMbDGravity</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGravity</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	aStream
		storeLevel: level
		title: 'ConstantGravity'
		object: gXYZ</body>

<body package="CADSM-Geo" selector="storePOVOn:level:">storePOVOn: aStream level: level 
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConstraintSet</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^true</body>

<body package="CADSM-Geo" selector="dataFromCurrentState">dataFromCurrentState
	| answer |
	answer := CADSMDataForceTorque new.
	answer aFIO: (StMFullColumn zero: 3).
	answer aTIO: (StMFullColumn zero: 3).
	^answer</body>

<body package="CADSM-Geo" selector="dataFromMbD">dataFromMbD
	"
	MbD returns aFIeO and aTIeO.
	 needs aFImO and aTImO.
	For Motion rImIeO is not zero and is changing.
	aFImO := aFIeO.
	aTImO := aTIeO + (rImIeO cross: aFIeO).
	"

	| aMbDUnits mbdItem answer aFIeO aTIeO rImIeO |
	aMbDUnits := self aMbDUnits.
	mbdItem := self mbdObject.
	answer := CADSMDataForceTorque new.
	aFIeO := mbdItem aFX * aMbDUnits force.
	aTIeO := mbdItem aTX * aMbDUnits torque.
	rImIeO := mbdItem frmI rmeO * aMbDUnits length.
	answer aFIO: aFIeO.
	answer aTIO: aTIeO + (rImIeO cross: aFIeO).
	^answer</body>

<body package="CADSM-Geo" selector="storeInputFromMbD">storeInputFromMbD
	"Do nothing."</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateForFrame1:">updateForFrame1: integer 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromInitiallyAssembledState">updateFromInitiallyAssembledState
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromInputState">updateFromInputState
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromMbD">updateFromMbD
	| data |
	data := self dataFromMbD.
	self dataSeries add: data</body>

<body package="CADSM-Geo" selector="validateFormulas">validateFormulas
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConstraintSet</class-id> <category>accessing</category>

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

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

<methods>
<class-id>CADSM.Geo.CADSMGeoRelativeConstraintSet</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="addCurrentStateToDataSeries">addCurrentStateToDataSeries
	super addCurrentStateToDataSeries.
	aMarkerI addCurrentStateToDataSeries.
	aMarkerJ addCurrentStateToDataSeries</body>

<body package="CADSM-Geo" selector="aEndI:aEndJ:">aEndI: aEndi aEndJ: aEndj 
	aMarkerI := aEndi.
	aMarkerJ := aEndj</body>

<body package="CADSM-Geo" selector="aMarkerI">aMarkerI
	^aMarkerI</body>

<body package="CADSM-Geo" selector="aMarkerI:">aMarkerI: markeri 
	aMarkerI := markeri</body>

<body package="CADSM-Geo" selector="aMarkerJ">aMarkerJ
	^aMarkerJ</body>

<body package="CADSM-Geo" selector="aMarkerJ:">aMarkerJ: markerj 
	aMarkerJ := markerj</body>

<body package="CADSM-Geo" selector="connectorList:">connectorList: collection 
	collection add: self</body>

<body package="CADSM-Geo" selector="dataClass">dataClass
	^StCAD.StGeo.GEOKineIForceIKineJ</body>

<body package="CADSM-Geo" selector="dataIntersectLine:tolerance:">dataIntersectLine: geoLine tolerance: tol 
	| jointLine answer |
	jointLine := CADSMGeoLine start: aMarkerI refFrame rOfO end: aMarkerJ refFrame rOfO.
	jointLine refFrame: self interface worldFrame.
	answer := jointLine dataIntersectLine: geoLine tolerance: tol.
	jointLine release.
	^answer</body>

<body package="CADSM-Geo" selector="dataSeriesForChart">dataSeriesForChart
	| kineIs kineJs forceIs index kineIforceIkineJ |
	kineIs := aMarkerI dataSeriesForChart.
	kineJs := aMarkerJ dataSeriesForChart.
	forceIs := self dataSeries.
	^(kineIs isSequenceable and: [kineJs isSequenceable and: [forceIs isSequenceable]])
		ifTrue: 
			[index := 0.
			kineIs
				collect: 
					[:kineI | 
					index := index + 1.
					kineIforceIkineJ := self dataClass new.
					kineIforceIkineJ kineI: (kineIs at: index).
					kineIforceIkineJ forceI: (forceIs at: index).
					kineIforceIkineJ kineJ: (kineJs at: index).
					kineIforceIkineJ]]
		ifFalse: 
			[Dialog warn: 'Simulation data is incomplete. Rerun a simulation.'.
			Array new]</body>

<body package="CADSM-Geo" selector="dataTypes">dataTypes
	^self dataClass new dataTypes</body>

<body package="CADSM-Geo" selector="markerI:markerJ:">markerI: markeri markerJ: markerj 
	aMarkerI := markeri.
	aMarkerJ := markerj</body>

<body package="CADSM-Geo" selector="newDataSeries">newDataSeries
	super newDataSeries.
	aMarkerI newDataSeries.
	aMarkerJ newDataSeries</body>

<body package="CADSM-Geo" selector="positionMemento">positionMemento
	| aMemento |
	aMemento := Polymorphic.GFMemento originator: self.
	aMemento addActionSelector: #yourself arguments: Array new.
	^aMemento</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRelativeConstraintSet</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| aConstraintSet |
	self dataSeries: OrderedCollection new.
	self discontinuities: OrderedCollection new.
	aConstraintSet := self aMbDClass new.
	aConstraintSet name: self fullName.
	aConstraintSet connectsI: aMarkerI aMbDObject toJ: aMarkerJ aMbDObject.
	aConstraintSet submitToSystem.
	self aMbDObject: aConstraintSet</body>

<body package="CADSM-Geo" selector="deleteMbD">deleteMbD
	super deleteMbD.
	aMarkerI deleteMbD.
	aMarkerJ deleteMbD</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	aMarkerI storeInputState.
	aMarkerJ storeInputState</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRelativeConstraintSet</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isConnectedTo:">isConnectedTo: markerList 
	^(markerList includes: aMarkerI)
		or: [markerList includes: aMarkerJ]</body>

<body package="CADSM-Geo" selector="isKineIJ">isKineIJ
	^false</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRelativeConstraintSet</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	aStream storeLevel: level title: self nameString.
	aStream
		storeLevel: level + 1
		title: 'Name'
		object: self name.
	aStream
		storeLevel: level + 1
		title: 'MarkerI'
		object: aMarkerI fullName.
	aStream
		storeLevel: level + 1
		title: 'MarkerJ'
		object: aMarkerJ fullName</body>

<body package="CADSM-Geo" selector="storePOVdatCurrentOn:">storePOVdatCurrentOn: aStream 
	| dataSeries fullNamePOV series |
	dataSeries := Array with: self dataFromCurrentState.
	fullNamePOV := self fullNamePOV.
	series := dataSeries collect: [:data | data aFIO].
	aStream storePOVTitle: fullNamePOV , '_FXonI'
		series: (series collect: [:data | data at: 1]).
	aStream storePOVTitle: fullNamePOV , '_FYonI'
		series: (series collect: [:data | data at: 2]).
	aStream storePOVTitle: fullNamePOV , '_FZonI'
		series: (series collect: [:data | data at: 3]).
	series := dataSeries collect: [:data | data aTIO].
	aStream storePOVTitle: fullNamePOV , '_TXonI'
		series: (series collect: [:data | data at: 1]).
	aStream storePOVTitle: fullNamePOV , '_TYonI'
		series: (series collect: [:data | data at: 2]).
	aStream storePOVTitle: fullNamePOV , '_TZonI'
		series: (series collect: [:data | data at: 3])</body>

<body package="CADSM-Geo" selector="storePOVOn:level:">storePOVOn: aStream level: level 
	aStream storePOVLevel: level
		title: ('// &lt;1s&gt;' expandMacrosWith: self fullNamePOV)</body>

<body package="CADSM-Geo" selector="storePOVTimeSeriesOn:">storePOVTimeSeriesOn: aStream 
	| dataSeries fullNamePOV series |
	dataSeries := self dataSeries.
	fullNamePOV := self fullNamePOV.
	series := dataSeries collect: [:data | data aFIO].
	aStream storePOVTitle: fullNamePOV , '_FXonI'
		series: (series collect: [:data | data at: 1]).
	aStream storePOVTitle: fullNamePOV , '_FYonI'
		series: (series collect: [:data | data at: 2]).
	aStream storePOVTitle: fullNamePOV , '_FZonI'
		series: (series collect: [:data | data at: 3]).
	series := dataSeries collect: [:data | data aTIO].
	aStream storePOVTitle: fullNamePOV , '_TXonI'
		series: (series collect: [:data | data at: 1]).
	aStream storePOVTitle: fullNamePOV , '_TYonI'
		series: (series collect: [:data | data at: 2]).
	aStream storePOVTitle: fullNamePOV , '_TZonI'
		series: (series collect: [:data | data at: 3])</body>

<body package="CADSM-Geo" selector="storeTimeSeriesOn:">storeTimeSeriesOn: aStream 
	| dataSeries series |
	aStream nextPutAll: self nameString; nextPutAll: 'Series'; space; nextPutAll: self fullName; cr.
	dataSeries := self dataSeries.
	series := dataSeries collect: [:data | data aFIO].
	aStream
		storeTitle: 'FXonI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	aStream
		storeTitle: 'FYonI'
		input: 0
		series: (series collect: [:data | data at: 2]).
	aStream
		storeTitle: 'FZonI'
		input: 0
		series: (series collect: [:data | data at: 3]).
	series := dataSeries collect: [:data | data aTIO].
	aStream
		storeTitle: 'TXonI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	aStream
		storeTitle: 'TYonI'
		input: 0
		series: (series collect: [:data | data at: 2]).
	aStream
		storeTitle: 'TZonI'
		input: 0
		series: (series collect: [:data | data at: 3])</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRelativeConstraintSet class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="aEndI:aEndJ:">aEndI: aEndi aEndJ: aEndj 
	^super new aEndI: aEndi aEndJ: aEndj</body>

<body package="CADSM-Geo" selector="markerI:markerJ:">markerI: markeri markerJ: markerj 
	^super new markerI: markeri markerJ: markerj</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoJoint</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isJoint">isJoint
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="cut">cut
	aSup cutJoint: self.
	super cut</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aSup addJoint: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCylSphJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'CylSphJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoInLineJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'InLineJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphericalJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDSphericalJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'SphericalJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelAxesJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDParallelAxesJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'ParallelAxesJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTranslationalJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDTranslationalJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'TranslationalJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGearJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'GearJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointInLineJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'PointInLineJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMotion</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isMotion">isMotion
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMotion</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="cut">cut
	aSup cutMotion: self.
	super cut</body>

<body package="CADSM-Geo" selector="functionParser">functionParser
	| parser |
	parser := StCAD.StGeo.MotionFunctionParser new.
	parser container: self.
	parser initVariables.
	^parser</body>

<body package="CADSM-Geo" selector="phiIJ">phiIJ
	^phiIJ</body>

<body package="CADSM-Geo" selector="phiIJ1">phiIJ1
	| coeffs phiIJcopy |
	^phiIJ isNil
		ifTrue: ['']
		ifFalse: [phiIJ isCharacters
				ifTrue: [phiIJ]
				ifFalse: 
					["For backward compatibility"
					phiIJcopy := phiIJ copy.
					coeffs := phiIJcopy coeffs collect: [:coeff | coeff value radiansToDegrees].
					phiIJcopy coeffs: coeffs.
					phiIJcopy displayString]]</body>

<body package="CADSM-Geo" selector="phiIJ:">phiIJ: function 
	phiIJ := function</body>

<body package="CADSM-Geo" selector="psiIJ">psiIJ
	^psiIJ</body>

<body package="CADSM-Geo" selector="psiIJ:">psiIJ: function 
	psiIJ := function</body>

<body package="CADSM-Geo" selector="theIJ">theIJ
	^theIJ</body>

<body package="CADSM-Geo" selector="theIJ:">theIJ: function 
	theIJ := function</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aSup addMotion: self</body>

<body package="CADSM-Geo" selector="xIJ">xIJ
	^xIJ</body>

<body package="CADSM-Geo" selector="xIJ:">xIJ: function 
	xIJ := function</body>

<body package="CADSM-Geo" selector="yIJ">yIJ
	^yIJ</body>

<body package="CADSM-Geo" selector="yIJ:">yIJ: function 
	yIJ := function</body>

<body package="CADSM-Geo" selector="zIJ">zIJ
	^zIJ</body>

<body package="CADSM-Geo" selector="zIJ1">zIJ1
	^zIJ isNil
		ifTrue: ['']
		ifFalse: ["For backward compatibility"
			zIJ displayString]</body>

<body package="CADSM-Geo" selector="zIJ:">zIJ: function 
	zIJ := function</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTranslationalMotion</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| zFunc parser stack func mbdZTranslation |
	super createMbD.
	zFunc := zIJ isNil
				ifTrue: [StMConstant with: 0]
				ifFalse: [zIJ isUserFunction
						ifTrue: 
							[parser := self functionParser.
							stack := parser
										parseUserFunction: zIJ
										notifying: nil
										ifFail: nil.
							func := stack last.
							func]
						ifFalse: [zIJ]].
	zFunc := (zFunc / self aMbDUnits length) createMbD simplified.
	mbdZTranslation := self mbdObject.
	mbdZTranslation zBlk: zFunc</body>

<body package="CADSM-Geo" selector="createMbD1">createMbD1
	| mbdZTranslation |
	super createMbD.
	mbdZTranslation := self mbdObject.
	mbdZTranslation zBlk: zIJ simplified</body>

<body package="CADSM-Geo" selector="validateFormulas">validateFormulas
	self zFunc</body>

<body package="CADSM-Geo" selector="zFunc">zFunc
	| parser stack func |
	^zIJ isNil
		ifTrue: [StMConstant with: 0]
		ifFalse: [zIJ isUserFunction
				ifTrue: 
					[parser := self functionParser.
					stack := parser
								parseUserFunction: zIJ
								notifying: nil
								ifFail: nil.
					func := stack last.
					func]
				ifFalse: [zIJ]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTranslationalMotion</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="joint">joint
	^self interface jointList detect: [:joint | ((joint isMemberOf: CADSMGeoTranslationalJoint)
			or: [joint isMemberOf: CADSMGeoCylindricalJoint])
			and: [joint aMarkerI == aMarkerI and: [joint aMarkerJ == aMarkerJ]]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTranslationalMotion</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	aStream storeLevel: level title: self nameString.
	aStream
		storeLevel: level + 1
		title: 'Name'
		object: self name.
	aStream
		storeLevel: level + 1
		title: 'MotionJoint'
		object: self joint fullName.
	aStream
		storeLevel: level + 1
		title: 'TranslationZ'
		object: zIJ</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTranslationalMotion class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDZTranslation</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'TranslationalMotion'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRevoluteJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDRevoluteJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'RevoluteJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGeneralMotion</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="angleIJJ">angleIJJ
	^StMFullColumn 
		with: phiIJ
		with: theIJ
		with: psiIJ</body>

<body package="CADSM-Geo" selector="angleIJJ:">angleIJJ: col 
	phiIJ := col at: 1.
	theIJ := col at: 2.
	psiIJ := col at: 3</body>

<body package="CADSM-Geo" selector="rIJI">rIJI
	^StMFullColumn 
		with: xIJ
		with: yIJ
		with: zIJ</body>

<body package="CADSM-Geo" selector="rIJI:">rIJI: col 
	xIJ := col at: 1.
	yIJ := col at: 2.
	zIJ := col at: 3</body>

<body package="CADSM-Geo" selector="rotOrder">rotOrder
	^rotOrder</body>

<body package="CADSM-Geo" selector="rotOrder:">rotOrder: col 
	rotOrder := col</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGeneralMotion</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| block mbdFullMotion length frIJI angle fangIJJ |
	super createMbD.
	block := 
			[:ufunc :mbdUnit | 
			| func parser stack |
			func := ufunc isNil 
						ifTrue: [StMConstant with: 0]
						ifFalse: 
							[parser := self functionParser.
							stack := parser 
										parseUserFunction: ufunc
										notifying: nil
										ifFail: nil.
							stack last].
			(func / mbdUnit) createMbD simplified].
	mbdFullMotion := self mbdObject.
	length := self aMbDUnits length.
	frIJI := StMFullColumn 
				with: (block value: xIJ value: length)
				with: (block value: yIJ value: length)
				with: (block value: zIJ value: length).
	angle := self aMbDUnits angle.
	fangIJJ := MbDEulerAngles 
				with: (block value: phiIJ value: angle)
				with: (block value: theIJ value: angle)
				with: (block value: psiIJ value: angle).
	fangIJJ rotOrder: rotOrder.
	mbdFullMotion frIJI: frIJI.
	mbdFullMotion fangIJJ: fangIJJ</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGeneralMotion</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream 
		storeLevel: level + 1
		title: 'rIJI1'
		object: xIJ.
	aStream 
		storeLevel: level + 1
		title: 'rIJI2'
		object: yIJ.
	aStream 
		storeLevel: level + 1
		title: 'rIJI3'
		object: zIJ.
	aStream 
		storeLevel: level + 1
		title: 'angIJJ1'
		object: phiIJ.
	aStream 
		storeLevel: level + 1
		title: 'angIJJ2'
		object: theIJ.
	aStream 
		storeLevel: level + 1
		title: 'angIJJ3'
		object: psiIJ.
	aStream 
		storeLevel: level + 1
		title: 'RotationOrder'
		object: rotOrder</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGeneralMotion class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDFullMotion</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'GeneralMotion'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAngleJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="theIzJz">theIzJz
	^theIzJz</body>

<body package="CADSM-Geo" selector="theIzJz:">theIzJz: anObject
	theIzJz := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAngleJoint</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream 
		storeLevel: level + 1
		title: 'theIzJz'
		object: theIzJz</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAngleJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDAngleJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'AngleJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoKineIJ</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isKineIJ">isKineIJ
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoKineIJ</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="cut">cut
	aSup cutKineIJ: self.
	super cut</body>

<body package="CADSM-Geo" selector="dataClass">dataClass
	^StCAD.StGeo.GEOKineIKineJ</body>

<body package="CADSM-Geo" selector="dataSeriesForChart">dataSeriesForChart
	| kineIs kineJs index kineIforceIkineJ |
	kineIs := aMarkerI dataSeriesForChart.
	kineJs := aMarkerJ dataSeriesForChart.
	^(kineIs isSequenceable and: [kineJs isSequenceable])
		ifTrue: 
			[index := 0.
			kineIs
				collect: 
					[:kineI | 
					index := index + 1.
					kineIforceIkineJ := self dataClass new.
					kineIforceIkineJ kineI: (kineIs at: index).
					kineIforceIkineJ kineJ: (kineJs at: index).
					kineIforceIkineJ]]
		ifFalse: 
			[Dialog warn: 'Simulation data is incomplete. Rerun a simulation.'.
			Array new]</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aSup addKineIJ: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoKineIJ</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromMbD">updateFromMbD
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoKineIJ class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'KinematicIJ'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRevCylJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="distanceIJ">distanceIJ
	^distanceIJ</body>

<body package="CADSM-Geo" selector="distanceIJ:">distanceIJ: anObject
	distanceIJ := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRevCylJoint</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream 
		storeLevel: level + 1
		title: 'distanceIJ'
		object: distanceIJ</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRevCylJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDRevCylJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'RevCylJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoScrewJoint</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| mbdScrewJoint |
	super createMbD.
	mbdScrewJoint := self mbdObject.
	mbdScrewJoint pitch: pitch / self aMbDUnits length</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoScrewJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="pitch">pitch
	^pitch</body>

<body package="CADSM-Geo" selector="pitch:">pitch: double 
	pitch := double</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoScrewJoint</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream
		storeLevel: level + 1
		title: 'pitch'
		object: pitch</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoScrewJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDScrewJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'ScrewJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRackPinJoint</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| mbdRackPinJoint |
	super createMbD.
	mbdRackPinJoint := self mbdObject.
	mbdRackPinJoint pitchRadius: pitchRadius / self aMbDUnits length</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRackPinJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="pitchRadius">pitchRadius
	^pitchRadius</body>

<body package="CADSM-Geo" selector="pitchRadius:">pitchRadius: double 
	pitchRadius := double</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRackPinJoint</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream
		storeLevel: level + 1
		title: 'pitchRadius'
		object: pitchRadius</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRackPinJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDRackPinJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'RackPinionJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAllowZRotation class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'AllowZRotation'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoFixedJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDFixedJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'FixedJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	name := #''.
	self aRefFrame: CADSMGeoCartesianFrame new.
	aRefFrame fixedAtRef.
	aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox new</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aAFf">aAFf
	^aRefFrame aAFf</body>

<body package="CADSM-Geo" selector="aBoundingBox">aBoundingBox
	^aBoundingBox ifNil: 
			[self calcBoundingBox.
			aBoundingBox]</body>

<body package="CADSM-Geo" selector="aBoundingBox:">aBoundingBox: anObject
	aBoundingBox := anObject</body>

<body package="CADSM-Geo" selector="aBoundingBoxF">aBoundingBoxF
	"In aRefFrame components."

	^self aBoundingBox inRefFrame: aRefFrame</body>

<body package="CADSM-Geo" selector="addMarkersIn:">addMarkersIn: set 
	"Do nothing."

	</body>

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

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

	aRefFrame addSub: argRefFrame</body>

<body package="CADSM-Geo" selector="aInputData">aInputData
	^(self triggerEvent: #InputData) ifNil: 
			[self storeInputState.
			self triggerEvent: #InputData]</body>

<body package="CADSM-Geo" selector="aInputData:">aInputData: aInputData 
	self removeActionsForEvent: #aInputData.
	aInputData ifNotNil:
			[self 
				when: #aInputData
				ask: aInputData
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="anyPart">anyPart
	^aSup anyPart</body>

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

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

<body package="CADSM-Geo" selector="aUI">aUI
	^self triggerEvent: #getUI</body>

<body package="CADSM-Geo" selector="aUI:">aUI: aUI 
	self removeActionsForEvent: #getUI.
	aUI ifNotNil: 
			[self 
				when: #getUI
				ask: aUI
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="cadObject">cadObject
	^self triggerEvent: #getCADObject</body>

<body package="CADSM-Geo" selector="cadObject:">cadObject: cadObject 
	self removeActionsForEvent: #getCADObject.
	cadObject ifNotNil:
			[self 
				when: #getCADObject
				ask: cadObject
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="container">container
	^aSup</body>

<body package="CADSM-Geo" selector="isFace">isFace
	^false</body>

<body package="CADSM-Geo" selector="isSketch">isSketch
	^false</body>

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

<body package="CADSM-Geo" selector="name:">name: anObject 
	name := anObject ifNotNil: [anObject asSymbol]</body>

<body package="CADSM-Geo" selector="rDfD">rDfD
	^self aMediator projectionFrame rDpPxfromrOpO: aRefFrame rOfO</body>

<body package="CADSM-Geo" selector="removeSub:">removeSub: aSub 
	aRefFrame removeSub: aSub aRefFrame</body>

<body package="CADSM-Geo" selector="rFfF">rFfF
	^aRefFrame rFfF</body>

<body package="CADSM-Geo" selector="treeNodesBlock">treeNodesBlock
	^
	[:items :displayString | 
	| child list |
	child := CADSM.UI.CADSMUITreeNode new.
	child geoItem: items.
	list := Core.List new: items size.
	items do: [:item | list add: item asTreeNode].
	list sortWith: [:node1 :node2 | node1 geoItem name &lt;= node2 geoItem name].
	child children: list.
	child displayString: displayString.
	child]</body>

<body package="CADSM-Geo" selector="_aRefFrame:">_aRefFrame: aaRefFrame 
	aRefFrame := aaRefFrame.
	aRefFrame body: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="calc">calc
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="calcBoundingBox">calcBoundingBox
	self privateCalcBoundingBox.
	aSup ifNotNil: [aSup clearBoundingBox]</body>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	self subclassResponsibility</body>

<body package="CADSM-Geo" selector="clearBoundingBox">clearBoundingBox
	aBoundingBox := nil</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox new.
	self privateCalcBoundingBox: self cItemWithBoundingBox</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox:">privateCalcBoundingBox: cSpatialItem 
	cSpatialItem do: 
			[:aSpatialItem | 
			aSpatialItem 
				ifNotNil: [aBoundingBox expandToBound: aSpatialItem aBoundingBoxF]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	name := nil.
	self aRefFrame: aRefFrame copy.
	self aBoundingBox: aBoundingBox copy</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	aRefFrame rFfF magnifySelf: aDouble.
	aBoundingBox magnifySelf: aDouble</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="is:kindOf:validFor:">is: aItem kindOf: itemClass validFor: cItem 
	| cnameSymbol aItemname |
	(aItem isKindOf: itemClass) ifFalse: [^false].
	(cItem anySatisfy: [:aaItem | aaItem == aItem]) ifTrue: [^false].
	cnameSymbol := cItem collect: 
					[:aaItem | 
					| nameSymbol |
					nameSymbol := aaItem name.
					self assert: [nameSymbol isSymbol].
					nameSymbol].
	aItemname := aItem name.
	(aItemname isNil or: 
			[self assert: [aItemname isSymbol].
			cnameSymbol includes: aItemname]) 
		ifTrue: 
			[| aString count newName |
			aString := aItem class name.
			count := 0.
			
			[count := count + 1.
			newName := (aString , count printString) asSymbol.
			cnameSymbol includes: newName] 
					whileTrue.
			aItem name: newName].
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpatialItem class</class-id> <category>events</category>

<body package="CADSM-Geo" selector="constructEventsTriggered">constructEventsTriggered
	^(super constructEventsTriggered)
		add: #getUI;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGeometry</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aModel">aModel
	^aSup aModel</body>

<body package="CADSM-Geo" selector="aNurbs">aNurbs
	^(self triggerEvent: #getNurbs) ifNil: 
			[| answer |
			answer := self createNurbs.
			self aNurbs: answer.
			answer]</body>

<body package="CADSM-Geo" selector="aNurbs:">aNurbs: aNurbs 
	self removeActionsForEvent: #getNurbs.
	aNurbs ifNotNil: 
			[self 
				when: #getNurbs
				ask: aNurbs
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aSketch">aSketch
	^aSup aSketch</body>

<body package="CADSM-Geo" selector="aSketchRefFrame">aSketchRefFrame
	^aSup aSketch aRefFrame</body>

<body package="CADSM-Geo" selector="create_glNurbs">create_glNurbs
	| answer aModelFrame aAMf rMfM |
	answer := self rfpfNurbs.
	answer isSpatial: isSpatial.
	isSpatial 
		ifTrue: 
			[aModelFrame := self aModel aRefFrame.
			aAMf := aRefFrame aAFfforF: aModelFrame.
			rMfM := aRefFrame rFpFfromrfpf: (StMFullColumn zero: 3) forF: aModelFrame]
		ifFalse: 
			[aAMf := aRefFrame aAFf.
			rMfM := aRefFrame rFfF].
	answer transformSelfBy_rFfF: rMfM aAFf: aAMf.
	answer conditionOpenGL.
	^answer</body>

<body package="CADSM-Geo" selector="glNurbs">glNurbs
	^(self triggerEvent: #glNurbs) ifNil: 
			[| answer |
			answer := self create_glNurbs.
			self glNurbs: answer.
			answer]</body>

<body package="CADSM-Geo" selector="glTrimNurbs">glTrimNurbs
	| answer aModelFrame aAMf rMfM |
	answer := self rfpfNurbs.
	answer isSpatial: isSpatial.
	isSpatial 
		ifTrue: 
			[aModelFrame := self aModel aRefFrame.
			aAMf := aRefFrame aAFfforF: aModelFrame.
			rMfM := aRefFrame rFpFfromrfpf: (StMFullColumn zero: 3) forF: aModelFrame]
		ifFalse: 
			[aAMf := aRefFrame aAFf.
			rMfM := aRefFrame rFfF].
	answer transformSelfBy_rFfF: rMfM aAFf: aAMf.
	answer conditionOpenGL.
	^answer</body>

<body package="CADSM-Geo" selector="isSpatial">isSpatial
	^isSpatial</body>

<body package="CADSM-Geo" selector="isSpatial:">isSpatial: anObject
	isSpatial := anObject</body>

<body package="CADSM-Geo" selector="removeSup">removeSup
	aSup ifNotNil: [:a | a removeGeometry: self]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoGeometry</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	isSpatial := true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="bottom">bottom
	^bottom</body>

<body package="CADSM-Geo" selector="bottom:">bottom: anObject
	bottom := anObject</body>

<body package="CADSM-Geo" selector="defaultDistance">defaultDistance
	^10.0d</body>

<body package="CADSM-Geo" selector="defaultPresentation">defaultPresentation
	^#solid</body>

<body package="CADSM-Geo" selector="defaultShading">defaultShading
	^#flatShading</body>

<body package="CADSM-Geo" selector="defaultViewFactor">defaultViewFactor
	^10</body>

<body package="CADSM-Geo" selector="distance">distance</body>

<body package="CADSM-Geo" selector="eyePoint">eyePoint
	^aRefFrame rOfO</body>

<body package="CADSM-Geo" selector="eyePoint:">eyePoint: eyePoint 
	| rFfF |
	rFfF := aRefFrame rFpFfromrOpO: eyePoint.
	aRefFrame rFfF: rFfF</body>

<body package="CADSM-Geo" selector="far">far
	^far</body>

<body package="CADSM-Geo" selector="far:">far: anObject
	far := anObject</body>

<body package="CADSM-Geo" selector="left">left
	^left</body>

<body package="CADSM-Geo" selector="left:">left: anObject
	left := anObject</body>

<body package="CADSM-Geo" selector="lineSmooth">lineSmooth
	^lineSmoothBoolean = true</body>

<body package="CADSM-Geo" selector="lineSmoothBoolean">lineSmoothBoolean
	^lineSmoothBoolean</body>

<body package="CADSM-Geo" selector="lineSmoothBoolean:">lineSmoothBoolean: anObject
	lineSmoothBoolean := anObject</body>

<body package="CADSM-Geo" selector="near">near
	^near</body>

<body package="CADSM-Geo" selector="near:">near: anObject
	near := anObject</body>

<body package="CADSM-Geo" selector="polygonSmooth">polygonSmooth
	^polygonSmoothBoolean = true</body>

<body package="CADSM-Geo" selector="polygonSmoothBoolean">polygonSmoothBoolean
	^polygonSmoothBoolean</body>

<body package="CADSM-Geo" selector="polygonSmoothBoolean:">polygonSmoothBoolean: anObject
	polygonSmoothBoolean := anObject</body>

<body package="CADSM-Geo" selector="presentation">presentation
	^presentation</body>

<body package="CADSM-Geo" selector="presentation:">presentation: anObject
	presentation := anObject</body>

<body package="CADSM-Geo" selector="ratio">ratio
	"distance to height ratio."

	^10</body>

<body package="CADSM-Geo" selector="removeSup">removeSup
	aSup ifNotNil: [:aaSup | aaSup removeCamera: self]</body>

<body package="CADSM-Geo" selector="right">right
	^right</body>

<body package="CADSM-Geo" selector="right:">right: anObject
	right := anObject</body>

<body package="CADSM-Geo" selector="shading">shading
	^shading</body>

<body package="CADSM-Geo" selector="shading:">shading: aSymbol 
	shading := aSymbol</body>

<body package="CADSM-Geo" selector="top">top
	^top</body>

<body package="CADSM-Geo" selector="top:">top: anObject
	top := anObject</body>

<body package="CADSM-Geo" selector="upVector">upVector
	^aRefFrame aAOf column: 2</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="renderOn:">renderOn: aRenderingContext 
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: cLighting size)
		addAll: cLighting;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id> <category>projection</category>

<body package="CADSM-Geo" selector="projectOn:">projectOn: aRenderingContext 
	presentation = #solidPresentation 
		ifTrue: [aRenderingContext solidPresentation].
	presentation = #wireframePresentation 
		ifTrue: [aRenderingContext wireframePresentation].
	presentation = #hiddenlinePresentation 
		ifTrue: [aRenderingContext hiddenlinePresentation].
	shading = #smoothShading ifTrue: [aRenderingContext smoothShading].
	shading = #flatShading ifTrue: [aRenderingContext flatShading].
	self lineSmooth 
		ifTrue: 
			[aRenderingContext lineSmoothNicest.
			aRenderingContext enableLineSmooth]
		ifFalse: [aRenderingContext disableLineSmooth].
	self polygonSmooth 
		ifTrue: 
			[aRenderingContext polygonSmoothFastest.
			aRenderingContext enablePolygonSmooth]
		ifFalse: [aRenderingContext disablePolygonSmooth]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isPerspective">isPerspective
	^false</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCamera</class-id> <category>shading</category>

<body package="CADSM-Geo" selector="flatShading">flatShading
	self shading: #flatShading</body>

<body package="CADSM-Geo" selector="smoothShading">smoothShading
	self shading: #smoothShading</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyLighting</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="isOn">isOn
	^isOn</body>

<body package="CADSM-Geo" selector="isOn:">isOn: aBoolean 
	isOn := aBoolean = true</body>

<body package="CADSM-Geo" selector="removeSup">removeSup
	aSup ifNotNil: [:aaSup | aaSup removeLighting: self]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyLighting</class-id> <category>lighting</category>

<body package="CADSM-Geo" selector="shineOn:">shineOn: aRenderingContext 
	isOn ifTrue: [self lightingOn: aRenderingContext]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyLighting</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="renderOn:">renderOn: aRenderingContext 
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyLighting</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	self privateCalcBoundingBox.
	isOn := true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyLighting class</class-id> <category>defaults</category>

<body package="CADSM-Geo" selector="defaultAlpha">defaultAlpha
	^1.0</body>

<body package="CADSM-Geo" selector="defaultColor">defaultColor
	^ColorValue white</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSingleLighting</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="alpha">alpha
	^alpha ifNil: [1.0]</body>

<body package="CADSM-Geo" selector="alpha:">alpha: anObject
	alpha := anObject</body>

<body package="CADSM-Geo" selector="color">color
	^color</body>

<body package="CADSM-Geo" selector="color:">color: anObject
	color := anObject</body>

<body package="CADSM-Geo" selector="setColor:alpha:">setColor: aColorValue alpha: aNumber 
	color := aColorValue.
	alpha := aNumber</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSingleLighting</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSMMiscBoundingBox origin: (StMFullColumn zero: 3)
				corner: (StMFullColumn zero: 3)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSingleLighting class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="color:">color: aColorValue 
	^self color: aColorValue alpha: self defaultAlpha</body>

<body package="CADSM-Geo" selector="color:alpha:">color: aColorValue alpha: aNumber 
	^self new setColor: aColorValue alpha: aNumber</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSpotLighting</class-id> <category>lighting</category>

<body package="CADSM-Geo" selector="lightingOn:">lightingOn: aRenderingContext 
	| index |
	index := aRenderingContext getLightIndex.
	aRenderingContext 
		lightIndex: index
		position: self position
		direction: (self direction isNil 
				ifTrue: [aRenderingContext projection sightPoint - self position]
				ifFalse: [self direction])
		cutoffAngle: (cutoffAngle isNil 
				ifTrue: [JunAngle fromDeg: 45]
				ifFalse: [cutoffAngle])
		color: self color
		alpha: self alpha.
	aRenderingContext enableLightIndex: index.
	aRenderingContext enableLighting</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelCamera</class-id> <category>projection</category>

<body package="CADSM-Geo" selector="projectOn:">projectOn: aRenderingContext 
	super projectOn: aRenderingContext.
	aRenderingContext parallelProjection: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelCamera</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="aRenderingContextExtent:">aRenderingContextExtent: extent 
	| dict aRenderingContext |
	dict := IdentityDictionary new: 5.
	dict at: #solid put: OpenGLSolidRenderingContext.
	dict at: #hiddenline put: OpenGLHiddenLineRenderingContext.
	dict at: #wireframe put: OpenGLWireframeRenderingContext.
	aRenderingContext := (dict at: presentation) extent: extent.
	aRenderingContext clear.
	aRenderingContext obeyParallelCamera: self.
	^aRenderingContext</body>

<body package="CADSM-Geo" selector="aRenderingContextOn:">aRenderingContextOn: aRetainedMedium 
	| dict aRenderingContext |
	dict := IdentityDictionary new: 5.
	dict at: #solid put: OpenGLSolidRenderingContext.
	dict at: #hiddenline put: OpenGLHiddenLineRenderingContext.
	dict at: #wireframe put: OpenGLWireframeRenderingContext.
	aRenderingContext := (dict at: presentation) on: aRetainedMedium.
	aRenderingContext clear.
	aRenderingContext obeyParallelCamera: self.
	^aRenderingContext</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelCamera</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	| aAFf rFfF |
	super initialize.
	aAFf := StMFullMatrix rotationMatrixFromzDir: (StMFullColumn 
						with: -1.0d
						with: -1.0d
						with: 1.0d)
				xDir: (StMFullColumn 
						with: 1.0d
						with: -1.0d
						with: 0.0d).
	rFfF := aAFf timesFullColumn: (StMFullColumn 
						with: 0.0d
						with: 0.0d
						with: 0.0d).
	aRefFrame rFfF: rFfF aAFf: aAFf.
	shading := self defaultShading.
	presentation := self defaultPresentation.
	lineSmoothBoolean := false.
	polygonSmoothBoolean := false.
	cLighting := CADSM.Misc.CADSMMiscOrderedSet new.
	self privateCalcBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelCamera</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="lineSmoothBoolean1">lineSmoothBoolean1
	^lineSmoothBoolean</body>

<body package="CADSM-Geo" selector="lineSmoothBoolean1:">lineSmoothBoolean1: anObject
	lineSmoothBoolean := anObject</body>

<body package="CADSM-Geo" selector="sightPoint">sightPoint
	^aRefFrame rOpOfromrfpf: (StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: 1.0d negated)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoUniverse</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	name := #CADSMGeoUniverse.
	self aRefFrame: CADSMGeoAbsoluteFrame new.
	cCamera := CADSM.Misc.CADSMMiscOrderedSet new.
	cLighting := CADSM.Misc.CADSMMiscOrderedSet new.
	cAssembly := self aSortedCollectionByName.
	self addCamera: CADSMGeoPerspectiveCamera new.
	self 
		addLighting: (CADSMGeoAmbientLighting color: ColorValue veryDarkGray copy).
	self 
		addLighting: (CADSMGeoParallelLighting color: ColorValue veryDarkGray copy
				direction: #(-1 0 0)).
	self 
		addLighting: (CADSMGeoParallelLighting color: ColorValue veryDarkGray copy
				direction: #(0 -1 0)).
	self 
		addLighting: (CADSMGeoParallelLighting color: ColorValue veryDarkGray copy
				direction: #(0 0 -1)).
	self calcBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoUniverse</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: 1)
		addAll: cCamera;
		addAll: cLighting;
		addAll: cAssembly;
		yourself</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := self aAbsoluteFrame boundingBox.
	self privateCalcBoundingBox: self cItemWithBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoUniverse</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^(cAssembly 
		detect: [:aAssembly | (aAssembly canUpdateForFrame: integer) not]
		ifNone: nil) isNil</body>

<body package="CADSM-Geo" selector="preRenderOn:">preRenderOn: renderingContext 
	cLighting do: [:aLighting | aLighting shineOn: renderingContext].
	renderingContext flush</body>

<body package="CADSM-Geo" selector="renderOn:">renderOn: aRenderingContext 
	self preRenderOn: aRenderingContext.
	aRenderingContext 
		pushName: self name
		transformation: aRefFrame aMFf
		while: 
			[aRefFrame renderOn: aRenderingContext.
			cCamera do: [:aCamera | aCamera renderOn: aRenderingContext].
			cLighting do: [:aLighting | aLighting renderOn: aRenderingContext].
			cAssembly do: [:aAssembly | aAssembly renderOn: aRenderingContext]]</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	cAssembly do: [:aAssembly | aAssembly updateForFrame: integer]</body>

<body package="CADSM-Geo" selector="viewAsHideLine">viewAsHideLine
	cCamera do: [:aCamera | aCamera presentation: #hiddenline]</body>

<body package="CADSM-Geo" selector="viewAsSolid">viewAsSolid
	cCamera do: [:aCamera | aCamera presentation: #solid]</body>

<body package="CADSM-Geo" selector="viewAsWireframe">viewAsWireframe
	cCamera do: [:aCamera | aCamera presentation: #wireframe]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoUniverse</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aAbsoluteFrame">aAbsoluteFrame
	^aRefFrame</body>

<body package="CADSM-Geo" selector="addAssembly">addAssembly
	^self addAssembly: CADSMGeoAssembly new</body>

<body package="CADSM-Geo" selector="addAssembly:">addAssembly: aAssembly 
	(self 
		is: aAssembly
		kindOf: CADSMGeoAssembly
		validFor: cAssembly) 
			ifTrue: 
				[aAssembly removeSup.
				super addRefFrame: aAssembly aRefFrame.
				cAssembly add: aAssembly.
				aAssembly aSup: self.
				self calcBoundingBox].
	^aAssembly</body>

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

	aCamera removeSup.
	super addRefFrame: aCamera aRefFrame.
	cCamera add: aCamera.
	aCamera aSup: self.
	self calcBoundingBox.
	^aCamera</body>

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

	aLighting removeSup.
	super addRefFrame: aLighting aRefFrame.
	cLighting add: aLighting.
	aLighting aSup: self.
	self calcBoundingBox.
	^aLighting</body>

<body package="CADSM-Geo" selector="aMbDUniverse">aMbDUniverse
	^self triggerEvent: #aMbDUniverse</body>

<body package="CADSM-Geo" selector="aMbDUniverse:">aMbDUniverse: mbdUniverse 
	self removeActionsForEvent: #aMbDUniverse.
	mbdUniverse ifNotNil: 
			[mbdUniverse aGeoUniverse: self.
			self 
				when: #aMbDUniverse
				ask: mbdUniverse
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="animationData">animationData
	^cAssembly first animationData</body>

<body package="CADSM-Geo" selector="asTreeNode">asTreeNode
	| answer |
	answer := super asTreeNode.
	answer
		addCollection: cCamera name: 'Cameras';
		addCollection: cLighting name: 'Lightings';
		addCollection: cAssembly name: 'Assemblies'.
	^answer</body>

<body package="CADSM-Geo" selector="boundingBox">boundingBox
	| answer |
	answer := aRefFrame boundingBox.
	cAssembly 
		do: [:aAssembly | answer := answer merge: aAssembly boundingBoxF].
	^answer</body>

<body package="CADSM-Geo" selector="cCamera">cCamera
	^cCamera</body>

<body package="CADSM-Geo" selector="cCamera:">cCamera: anObject
	cCamera := anObject</body>

<body package="CADSM-Geo" selector="cLighting">cLighting
	^cLighting</body>

<body package="CADSM-Geo" selector="cLighting:">cLighting: anObject
	cLighting := anObject</body>

<body package="CADSM-Geo" selector="displayLightCollection">displayLightCollection
	^cLighting</body>

<body package="CADSM-Geo" selector="displayObject">displayObject
	^cAssembly</body>

<body package="CADSM-Geo" selector="isValidAssembly:">isValidAssembly: aAssembly 
	| nameList |
	(cAssembly anySatisfy: [:aaAssembly | aaAssembly == aAssembly]) 
		ifTrue: [^false].
	nameList := cAssembly collect: [:aItem | aItem name].
	(aAssembly name isNil or: [nameList includes: aAssembly name asSymbol]) 
		ifTrue: 
			[| aString count newName |
			aString := aAssembly class name.
			count := 0.
			
			[count := count + 1.
			newName := (aString , count printString) asSymbol.
			nameList includes: newName] 
					whileTrue.
			aAssembly name: newName]
		ifFalse: [aAssembly name: aAssembly name asSymbol].
	^true</body>

<body package="CADSM-Geo" selector="mbdProcess">mbdProcess
	^self triggerEvent: #mbdProcess</body>

<body package="CADSM-Geo" selector="mbdProcess:">mbdProcess: mbdProcess 
	self removeActionsForEvent: #mbdProcess.
	mbdProcess ifNotNil: 
			[self 
				when: #mbdProcess
				ask: mbdProcess
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="removeCamera:">removeCamera: aCamera 
	super removeSub: aCamera.
	cCamera remove: aCamera ifAbsent: [nil].
	aCamera aSup: nil.
	^aCamera</body>

<body package="CADSM-Geo" selector="removeLighting:">removeLighting: aLighting 
	super removeSub: aLighting.
	cLighting remove: aLighting ifAbsent: [nil].
	aLighting aSup: nil.
	^aLighting</body>

<body package="CADSM-Geo" selector="timeSeries">timeSeries
	^cAssembly first timeSeries</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoUniverse</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="activeAssembly">activeAssembly
	^cAssembly at: 1</body>

<body package="CADSM-Geo" selector="isUniverse">isUniverse
	^true</body>

<body package="CADSM-Geo" selector="logString:">logString: string 
	Transcript logString: string</body>

<body package="CADSM-Geo" selector="preMbDrun">preMbDrun
	(self activeAssembly)
		calcCharacteristicDimensions;
		deleteMbD;
		createMbD</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoArrayLighting</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: cLighting size)
		addAll: cLighting;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerpendicularJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDPerpendicularJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'PerpendicularJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointLighting</class-id> <category>lighting</category>

<body package="CADSM-Geo" selector="lightingOn:">lightingOn: aRenderingContext 
	| index |
	index := aRenderingContext getLightIndex.
	aRenderingContext 
		lightIndex: index
		position: self position
		direction: nil
		cutoffAngle: nil
		color: self color
		alpha: self alpha.
	aRenderingContext enableLightIndex: index.
	aRenderingContext enableLighting</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCVCVJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="coeffRestitution">coeffRestitution
	^coeffRestitution</body>

<body package="CADSM-Geo" selector="coeffRestitution:">coeffRestitution: double 
	coeffRestitution := double</body>

<body package="CADSM-Geo" selector="cut">cut
	aMarkerI cut.
	aMarkerJ cut.
	super cut</body>

<body package="CADSM-Geo" selector="faceI:faceJ:">faceI: facei faceJ: facej 
	aMarkerI := CADSMGeoCurveMarker newOnFace: facei.
	aMarkerJ := CADSMGeoCurveMarker newOnFace: facej</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aMarkerI uncut.
	aMarkerJ uncut.
	super uncut</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCVCVJoint</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	(super canUpdateForFrame: integer)
		ifFalse: [^false].
	(aMarkerI canUpdateForFrame: integer)
		ifFalse: [^false].
	(aMarkerJ canUpdateForFrame: integer)
		ifFalse: [^false].
	^true</body>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| mbdCVCVJoint |
	super createMbD.
	mbdCVCVJoint := self mbdObject.
	mbdCVCVJoint coeffRestitution: coeffRestitution</body>

<body package="CADSM-Geo" selector="dataFromMbD">dataFromMbD
	"
	MbD returns aFIeO and aTIeO.
	 needs aFImO and aTImO.
	For CVCV geoIm = mbdIe.
	aFImO := aFIeO.
	aTImO := aTIeO.
	"

	| aMbDUnits mbdItem answer aFIeO aTIeO |
	aMbDUnits := self aMbDUnits.
	mbdItem := self mbdObject.
	answer := CADSMDataForceTorque new.
	aFIeO := mbdItem aFX * aMbDUnits force.
	aTIeO := mbdItem aTX * aMbDUnits torque.
	answer aFIO: aFIeO.
	answer aTIO: aTIeO.
	^answer</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	super updateForFrame: integer.
	aMarkerI updateForFrame: integer.
	aMarkerJ updateForFrame: integer</body>

<body package="CADSM-Geo" selector="updateFromInitiallyAssembledState">updateFromInitiallyAssembledState
	super updateFromInitiallyAssembledState.
	aMarkerI updateFromInitiallyAssembledState.
	aMarkerJ updateFromInitiallyAssembledState</body>

<body package="CADSM-Geo" selector="updateFromInputState">updateFromInputState
	super updateFromInputState.
	aMarkerI updateFromInputState.
	aMarkerJ updateFromInputState</body>

<body package="CADSM-Geo" selector="updateFromMbD">updateFromMbD
	super updateFromMbD.
	aMarkerI updateFromMbD.
	aMarkerJ updateFromMbD</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCVCVJoint</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream
		storeLevel: level + 1
		title: 'coeffRestitution'
		object: coeffRestitution</body>

<body package="CADSM-Geo" selector="storeTimeSeriesOn:">storeTimeSeriesOn: aStream 
	| dataSeries series |
	super storeTimeSeriesOn: aStream.
	dataSeries := aMarkerI dataSeries.
	series := dataSeries collect: [:data | data s].
	aStream
		storeTitle: 'sI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	series := dataSeries collect: [:data | data sdot].
	aStream
		storeTitle: 'sdotI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	series := dataSeries collect: [:data | data sddot].
	aStream
		storeTitle: 'sddotI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	dataSeries := aMarkerJ dataSeries.
	series := dataSeries collect: [:data | data s].
	aStream
		storeTitle: 'sJ'
		input: 0
		series: (series collect: [:data | data at: 1]).
	series := dataSeries collect: [:data | data sdot].
	aStream
		storeTitle: 'sdotJ'
		input: 0
		series: (series collect: [:data | data at: 1]).
	series := dataSeries collect: [:data | data sddot].
	aStream
		storeTitle: 'sddotJ'
		input: 0
		series: (series collect: [:data | data at: 1])</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCVCVJoint class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="faceI:faceJ:">faceI: facei faceJ: facej 
	^super new faceI: facei faceJ: facej</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCVCVJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aMbDClass">aMbDClass
	^CADSMMbDFullySeparatedCVCVJoint</body>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^CADSMMbDFullySeparatedCVCVJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'CurveCurveContact'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyPart</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aCFD">aCFD
	^self triggerEvent: #getCFD</body>

<body package="CADSM-Geo" selector="aCFD:">aCFD: aCFD 
	self removeActionsForEvent: #getCFD.
	aCFD ifNotNil: 
			[self 
				when: #getCFD
				ask: aCFD
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aFEM">aFEM
	^self triggerEvent: #getFEM</body>

<body package="CADSM-Geo" selector="aFEM:">aFEM: aFEM 
	self removeActionsForEvent: #getFEM.
	aFEM ifNotNil: 
			[self 
				when: #getFEM
				ask: aFEM
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aMbD">aMbD
	^self triggerEvent: #getMbD</body>

<body package="CADSM-Geo" selector="aMbD:">aMbD: aMbD 
	self removeActionsForEvent: #getMbD.
	aMbD ifNotNil: 
			[self 
				when: #getMbD
				ask: aMbD
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="anyPart">anyPart
	^self</body>

<body package="CADSM-Geo" selector="dataFromCurrentState">dataFromCurrentState
	^(CADSMDataPosVelAcc new)
		rFfF: aRefFrame rOfO;
		aAFf: aRefFrame aAOf;
		vFfF: aRefFrame vOfO;
		omeFfF: aRefFrame omeOfO;
		aFfF: aRefFrame aOfO;
		alpFfF: aRefFrame alpOfO;
		yourself</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	self aInputData: self dataFromCurrentState</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyPart</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^[(self dataSeries at: integer) notNil] 
		on: Object subscriptOutOfBoundsSignal
		do: [:ex | ex return: false]</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	| data |
	data := self dataSeries at: integer.
	aRefFrame quietlyrOfO: data rOfO aAOf: data aAOf.
	aRefFrame quietlyvOfO: data vOfO omeOfO: data omeOfO</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAnyPart class</class-id> <category>events</category>

<body package="CADSM-Geo" selector="constructEventsTriggered">constructEventsTriggered
	^(super constructEventsTriggered)
		add: #getMbD;
		add: #getFEM;
		add: #getCFD;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aAPcm">aAPcm
	^self aMassMarker aRefFrame aAFf</body>

<body package="CADSM-Geo" selector="addFeature:">addFeature: aFeature 
	aNMT addFeature: aFeature</body>

<body package="CADSM-Geo" selector="addFeatureOrder:">addFeatureOrder: cFeature 
	cFeature do: [:aFeature | aNMT addFeature: aFeature]</body>

<body package="CADSM-Geo" selector="addRefCurve:">addRefCurve: aRefCurve 
	^self addRefGeo: aRefCurve</body>

<body package="CADSM-Geo" selector="addRefCurves:">addRefCurves: cRefCurve 
	cRefCurve do: [:aRefCurve | self addRefCurve: aRefCurve]</body>

<body package="CADSM-Geo" selector="addRefGeo:">addRefGeo: aRefGeo 
	(self 
		is: aRefGeo
		kindOf: CADSMGeoRefGeo
		validFor: cRefGeo) 
			ifTrue: 
				[aRefGeo removeSup.
				super addRefFrame: aRefGeo aRefFrame.
				cRefGeo add: aRefGeo.
				aRefGeo aSup: self.
				self calcBoundingBox].
	^aRefGeo</body>

<body package="CADSM-Geo" selector="addRefPoint:">addRefPoint: aRefPoint 
	^self addRefGeo: aRefPoint</body>

<body package="CADSM-Geo" selector="addRefPoints:">addRefPoints: cRefPoint 
	cRefPoint do: [:aRefPoint | self addRefPoint: aRefPoint]</body>

<body package="CADSM-Geo" selector="addRefSurface:">addRefSurface: aRefSurface 
	^self addRefGeo: aRefSurface</body>

<body package="CADSM-Geo" selector="addRefSurfaces:">addRefSurfaces: cRefSurface 
	cRefSurface do: [:aRefSurface | self addRefSurface: aRefSurface]</body>

<body package="CADSM-Geo" selector="aMassMarker">aMassMarker
	^aMassMarker</body>

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

	argMassMarker removeSup.
	super addRefFrame: argMassMarker aRefFrame.
	aMassMarker := argMassMarker.
	argMassMarker aSup: self.
	self calcBoundingBox.
	^argMassMarker</body>

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

	argNMT removeSup.
	aNMT := argNMT.
	argNMT aSup: self.
	^argNMT</body>

<body package="CADSM-Geo" selector="asTreeNode">asTreeNode
	^(super asTreeNode)
		addCollection: aNMT cFeature name: 'Features';
		addCollection: cRefGeo name: 'Markers';
		addChild: aMassMarker;
		yourself</body>

<body package="CADSM-Geo" selector="findMarkerNamed:">findMarkerNamed: nameComponents 
	| cShortenedNameComponent answer |
	self name = (nameComponents at: 1) ifFalse: [^nil].
	cShortenedNameComponent := nameComponents copyFrom: 2
				to: nameComponents size.
	cRefGeo do: 
			[:aMarker | 
			(answer := aMarker findMarkerNamed: cShortenedNameComponent) 
				ifNotNil: [^answer]].
	^answer</body>

<body package="CADSM-Geo" selector="findMarkerNamedOld:">findMarkerNamedOld: nameComponents 
	| cShortenedNameComponent answer |
	self name = (nameComponents at: 1) ifFalse: [^nil].
	cShortenedNameComponent := nameComponents copyFrom: 2
				to: nameComponents size.
	cRefGeo do: 
			[:aMarker | 
			(answer := aMarker findMarkerNamedOld: cShortenedNameComponent) 
				ifNotNil: [^answer]].
	^answer</body>

<body package="CADSM-Geo" selector="mass">mass
	^self aMassMarker mass</body>

<body package="CADSM-Geo" selector="mJpp">mJpp
	^self aMassMarker mJpp</body>

<body package="CADSM-Geo" selector="qEp">qEp
	^aMassMarker qEp</body>

<body package="CADSM-Geo" selector="removeSup">removeSup
	aSup ifNotNil: [:aaSup | aaSup removePart: self]</body>

<body package="CADSM-Geo" selector="rOcmO">rOcmO
	^self aMassMarker rOcmO</body>

<body package="CADSM-Geo" selector="rPcmP">rPcmP
	^self aMassMarker aRefFrame rFfF</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	super storeInputState.
	cRefGeo do: [:item | item storeInputState]</body>

<body package="CADSM-Geo" selector="vOcmO">vOcmO
	| vOPO omeOPO rPcmO |
	vOPO := aRefFrame vOfO.
	omeOPO := aRefFrame omeOfO.
	vOPO isNil ifTrue: [vOPO := StMFullColumn zero: 3].
	omeOPO isNil ifTrue: [omeOPO := StMFullColumn zero: 3].
	rPcmO := aMassMarker rOcmO - aRefFrame rOfO.
	^vOPO + (omeOPO cross: rPcmO)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	cRefGeo := CADSM.Misc.CADSMMiscOrderedSet new.
	self aNMT: CADSM.NMT.CADSMNMTModel new</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>NMT</category>

<body package="CADSM-Geo" selector="privateBuildSolidModel">privateBuildSolidModel
	aNMT privateBuildSolidModel</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="renderOn:">renderOn: aRenderingContext 
	aRenderingContext 
		pushName: self name
		transformation: aRefFrame aMFf
		while: [aNMT renderOn: aRenderingContext]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: 1 + cRefGeo size + 1)
		add: aMassMarker;
		addAll: cRefGeo;
		add: aNMT;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>MbD</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	"MbDMarkers are created on demand by joints, forces, etc."

	| aMbDUnits aMbDPart |
	self dataSeries: OrderedCollection new.
	aMbDUnits := self aMbDUnits.
	aMbDPart := CADSMMbDPart new.
	self mbdObject: aMbDPart.
	aMbDPart name: self fullName.
	aMbDPart m: self mass / aMbDUnits mass.
	aMbDPart aJ: self mJpp / aMbDUnits aJ.
	aMbDPart qX: self rOcmO / aMbDUnits length.
	aMbDPart qE: self qEp.
	aMbDPart qXdot: self vOcmO / aMbDUnits velocity.
	aMbDPart omeOpO: self omeOpO / aMbDUnits omega.
	aMbDPart qXddot: (StMFullColumn zero: 3).
	aMbDPart qEddot: (StMFullColumn zero: 4).
	aSup mbdObject addAnyPart: aMbDPart</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPart</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="omeOpO">omeOpO
	^aRefFrame omeOfO</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aAnimationData">aAnimationData
	| dataSeries answer nseries |
	dataSeries := self dataSeries.
	nseries := dataSeries isNil ifTrue: [0] ifFalse: [dataSeries size].
	answer := self triggerEvent: #getAnimationData.
	answer ifNil: 
			[answer := CADSMDataAnimation new.
			self aAnimationData: answer].
	answer nframe: nseries.
	^answer</body>

<body package="CADSM-Geo" selector="aAnimationData:">aAnimationData: aAnimationData 
	self removeActionsForEvent: #getAnimationData.
	aAnimationData ifNotNil: 
			[self 
				when: #getAnimationData
				ask: aAnimationData
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="addAnyPart:">addAnyPart: aAnyPart 
	(self 
		is: aAnyPart
		kindOf: CADSMGeoAnyPart
		validFor: cAnyPart) 
			ifTrue: 
				[aAnyPart removeSup.
				super addRefFrame: aAnyPart aRefFrame.
				cAnyPart add: aAnyPart.
				aAnyPart aSup: self.
				self calcBoundingBox].
	^aAnyPart</body>

<body package="CADSM-Geo" selector="addAssembly:">addAssembly: aAssembly 
	^self addAnyPart: aAssembly</body>

<body package="CADSM-Geo" selector="addcAnyPart:">addcAnyPart: arrayAnyPart 
	arrayAnyPart do: [:aAnyPart | self addAnyPart: aAnyPart]</body>

<body package="CADSM-Geo" selector="addConstraintSet:">addConstraintSet: aConstraintSet 
	(self 
		is: aConstraintSet
		kindOf: CADSMGeoConstraintSet
		validFor: cConstraintSet) 
			ifTrue: 
				[aConstraintSet removeSup.
				cConstraintSet add: aConstraintSet.
				aConstraintSet aSup: self].
	^aConstraintSet</body>

<body package="CADSM-Geo" selector="addForceTorque:">addForceTorque: aForceTorque 
	(self 
		is: aForceTorque
		kindOf: CADSMGeoForceTorque
		validFor: cForceTorque) 
			ifTrue: 
				[aForceTorque removeSup.
				cForceTorque add: aForceTorque.
				aForceTorque aSup: self].
	^aForceTorque</body>

<body package="CADSM-Geo" selector="addForceTorques:">addForceTorques: arrayForceTorque 
	arrayForceTorque do: [:aForceTorque | self addForceTorque: aForceTorque]</body>

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

	aGeneralConstraintSet removeSup.
	cConstraintSet add: aGeneralConstraintSet.
	aGeneralConstraintSet aSup: self.
	^aGeneralConstraintSet</body>

<body package="CADSM-Geo" selector="addGeneralConstraintSets:">addGeneralConstraintSets: cGeneralConstraintSet 
	cGeneralConstraintSet 
		do: [:aGeneralConstraintSet | self addGeneralConstraintSet: aGeneralConstraintSet]</body>

<body package="CADSM-Geo" selector="addJoint:">addJoint: aJoint 
	^self addConstraintSet: aJoint</body>

<body package="CADSM-Geo" selector="addJoints:">addJoints: cJoint 
	cJoint do: [:aJoint | self addJoint: aJoint]</body>

<body package="CADSM-Geo" selector="addKinematicIJs:">addKinematicIJs: cKinematicIJ 
	cKinematicIJ do: [:aKinematicIJ | self addKineIJ: aKinematicIJ]</body>

<body package="CADSM-Geo" selector="addMotion:">addMotion: aMotion 
	^self addConstraintSet: aMotion</body>

<body package="CADSM-Geo" selector="addMotions:">addMotions: cMotion 
	cMotion do: [:aMotion | self addMotion: aMotion]</body>

<body package="CADSM-Geo" selector="addRefCurve:">addRefCurve: aRefCurve 
	^self aOriginPart addRefCurve: aRefCurve</body>

<body package="CADSM-Geo" selector="addRefCurves:">addRefCurves: cRefCurve 
	cRefCurve do: [:aRefCurve | self addRefCurve: aRefCurve]</body>

<body package="CADSM-Geo" selector="addRefPoints:">addRefPoints: cRefPoint 
	cRefPoint do: [:aRefPoint | self addRefPoint: aRefPoint]</body>

<body package="CADSM-Geo" selector="addRefSurface:">addRefSurface: aRefSurface 
	^self aOriginPart addRefSurface: aRefSurface</body>

<body package="CADSM-Geo" selector="addRefSurfaces:">addRefSurfaces: cRefSurface 
	cRefSurface do: [:aRefSurface | self addRefSurface: aRefSurface]</body>

<body package="CADSM-Geo" selector="aGeoTime">aGeoTime
	^(self triggerEvent: #aGeoTime) ifNil: 
			[| answer |
			answer := CADSM.Geo.CADSMGeoTime new.
			self aGeoTime: answer.
			answer]</body>

<body package="CADSM-Geo" selector="aGeoTime:">aGeoTime: aGeoTime 
	self removeActionsForEvent: #aGeoTime.
	^aGeoTime ifNotNil: 
			[aGeoTime aSup: self.
			self 
				when: #aGeoTime
				ask: aGeoTime
				perform: #yourself.
			aGeoTime]</body>

<body package="CADSM-Geo" selector="aGravity">aGravity
	^(self triggerEvent: #getGravity) ifNil: 
			[| answer |
			answer := CADSMGeoGravity new 
						gX: 0.0d
						gY: 0.0d
						gZ: 0.0d.
			self aGravity: answer.
			answer]</body>

<body package="CADSM-Geo" selector="aGravity:">aGravity: aGravity 
	self removeActionsForEvent: #aGravity.
	aGravity ifNotNil: 
			[aGravity removeSup.
			aGravity aSup: self.
			self 
				when: #aGravity
				ask: aGravity
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aMbDUnits">aMbDUnits
	^self triggerEvent: #aMbDUnits</body>

<body package="CADSM-Geo" selector="aMbDUnits:">aMbDUnits: aMbDUnits 
	self removeActionsForEvent: #aMbDUnits.
	aMbDUnits ifNotNil: 
			[self 
				when: #aMbDUnits
				ask: aMbDUnits
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="aOriginPart">aOriginPart
	^cAnyPart at: 1</body>

<body package="CADSM-Geo" selector="aSimulationData">aSimulationData
	^(self triggerEvent: #getSimulationData) ifNil: 
			[| answer |
			answer := CADSMDataSimulation new.
			self aSimulationData: answer.
			answer]</body>

<body package="CADSM-Geo" selector="aSimulationData:">aSimulationData: simulationData 
	self removeActionsForEvent: #getSimulationData.
	simulationData ifNotNil: 
			[self 
				when: #getSimulationData
				ask: simulationData
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="asTreeNode">asTreeNode
	^(super asTreeNode)
		addCollection: cAnyPart name: 'Parts';
		addCollection: cConstraintSet name: 'Constraints';
		addCollection: cForceTorque name: 'ForceTorques';
		addCollection: cField name: 'Fields';
		addCollection: cVariable name: 'Variables';
		yourself</body>

<body package="CADSM-Geo" selector="cDataPosVelAcc">cDataPosVelAcc
	^self triggerEvent: #cDataPosVelAcc</body>

<body package="CADSM-Geo" selector="cDataPosVelAcc:">cDataPosVelAcc: cDataPosVelAcc 
	self removeActionsForEvent: #cDataPosVelAcc.
	cDataPosVelAcc ifNotNil: 
			[self 
				when: #cDataPosVelAcc
				ask: cDataPosVelAcc
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="connectorList">connectorList
	| answer |
	answer := OrderedCollection new.
	self jointList do: [:geoIJ | answer add: geoIJ].
	self motionList do: [:geoIJ | answer add: geoIJ].
	self kineIJList do: [:geoIJ | answer add: geoIJ].
	self forceTorqueList do: [:geoIJ | answer add: geoIJ].
	^answer</body>

<body package="CADSM-Geo" selector="cTimeAtDiscontinuity">cTimeAtDiscontinuity
	^self triggerEvent: #cTimeAtDiscontinuity</body>

<body package="CADSM-Geo" selector="cTimeAtDiscontinuity:">cTimeAtDiscontinuity: cTimeAtDiscontinuity 
	self removeActionsForEvent: #cTimeAtDiscontinuity.
	cTimeAtDiscontinuity ifNotNil: 
			[self 
				when: #cTimeAtDiscontinuity
				ask: cTimeAtDiscontinuity
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="findMarkerNamed:">findMarkerNamed: nameComponents 
	| cShortenedNameComponent answer |
	self name = (nameComponents at: 1) ifFalse: [^nil].
	cShortenedNameComponent := nameComponents copyFrom: 2
				to: nameComponents size.
	cAnyPart do: 
			[:aAnyPart | 
			(answer := aAnyPart findMarkerNamed: cShortenedNameComponent) 
				ifNotNil: [^answer]].
	^answer</body>

<body package="CADSM-Geo" selector="findMarkerNamedOld:">findMarkerNamedOld: nameComponents 
	| cShortenedNameComponent answer |
	self name = (nameComponents at: 1) ifFalse: [^nil].
	cShortenedNameComponent := nameComponents copyFrom: 2
				to: nameComponents size.
	cAnyPart do: 
			[:aAnyPart | 
			(answer := aAnyPart findMarkerNamedOld: cShortenedNameComponent) 
				ifNotNil: [^answer]].
	^answer</body>

<body package="CADSM-Geo" selector="forceTorqueList">forceTorqueList
	^cForceTorque asSortedCollection: [:a :b | a name &lt;= b name]</body>

<body package="CADSM-Geo" selector="gravity:">gravity: gravity 
	self removeActionsForEvent: #getGravity.
	gravity ifNotNil: 
			[gravity removeSup.
			gravity aSup: self.
			self 
				when: #getGravity
				ask: gravity
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="jointList">jointList
	^(cConstraintSet select: [:set | set isJoint]) 
		asSortedCollection: [:a :b | a name &lt;= b name]</body>

<body package="CADSM-Geo" selector="kineIJList">kineIJList
	^(cConstraintSet select: [:set | set isKineIJ]) 
		asSortedCollection: [:a :b | a name &lt;= b name]</body>

<body package="CADSM-Geo" selector="motionList">motionList
	^(cConstraintSet select: [:set | set isMotion]) 
		asSortedCollection: [:a :b | a name &lt;= b name]</body>

<body package="CADSM-Geo" selector="partList">partList
	^cAnyPart asSortedCollection: [:a :b | a name &lt;= b name]</body>

<body package="CADSM-Geo" selector="removeSup">removeSup
	aSup ifNotNil: [:aaSup | aaSup removeAssembly: self]</body>

<body package="CADSM-Geo" selector="timeSeries">timeSeries
	^self triggerEvent: #getTimeSeries</body>

<body package="CADSM-Geo" selector="timeSeries:">timeSeries: timeSeries 
	self removeActionsForEvent: #getTimeSeries.
	timeSeries ifNotNil: 
			[self 
				when: #getTimeSeries
				ask: timeSeries
				perform: #yourself]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	cAnyPart := CADSM.Misc.CADSMMiscOrderedSet new.
	cConstraintSet := CADSM.Misc.CADSMMiscOrderedSet new.
	cForceTorque := CADSM.Misc.CADSMMiscOrderedSet new.
	cField := CADSM.Misc.CADSMMiscOrderedSet new.
	cVariable := CADSM.Misc.CADSMMiscOrderedSet new</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="renderOn:">renderOn: aRenderingContext 
	aRenderingContext 
		pushName: self name
		transformation: aRefFrame aMFf
		while: [cAnyPart do: [:aAnyPart | aAnyPart renderOn: aRenderingContext]]</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	super updateForFrame: integer.
	cAnyPart do: [:aAnyPart | aAnyPart updateForFrame: integer].
	cConstraintSet 
		do: [:aConstraintSet | aConstraintSet updateForFrame: integer].
	cForceTorque do: [:aForceTorque | aForceTorque updateForFrame: integer]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="calcCharacteristicDimensions">calcCharacteristicDimensions
	| unitMass unitLength unitTime unitAngle |
	unitTime := self calcCharacteristicTime.
	unitMass := self calcCharacteristicMass.
	unitLength := self calcCharacteristicLength.
	unitAngle := 1.0d.
	"	self halt: 'For debug only'.
	unitTime := 1.0d.
	unitMass := 1.0d.
	unitLength := 1.0d.
	unitAngle := 1.0d."
	self aMbDUnits: (StMUnits 
				time: unitTime
				mass: unitMass
				length: unitLength
				angle: unitAngle)</body>

<body package="CADSM-Geo" selector="calcCharacteristicLength">calcCharacteristicLength
	| lengths sumOfSquares unitLength |
	lengths := OrderedCollection new.
	self connectorList do: 
			[:geoIJ | 
			lengths add: geoIJ aMarkerI rpmp length.
			lengths add: geoIJ aMarkerJ rpmp length].
	sumOfSquares := lengths inject: 0.0d
				into: [:subtotal :length | subtotal + (length * length)].
	unitLength := (sumOfSquares / (lengths size max: 1)) sqrt.
	unitLength &lt;= 0 ifTrue: [unitLength := 1.0d].
	^unitLength</body>

<body package="CADSM-Geo" selector="calcCharacteristicMass">calcCharacteristicMass
	| masses sumOfSquares unitMass |
	masses := self partList collect: [:part | part mass].
	sumOfSquares := masses inject: 0.0d
				into: [:subtotal :mass | subtotal + (mass * mass)].
	unitMass := (sumOfSquares / masses size) sqrt.
	unitMass &lt;= 0 ifTrue: [unitMass := 1.0d].
	^unitMass</body>

<body package="CADSM-Geo" selector="calcCharacteristicTime">calcCharacteristicTime
	^self aSimulationData hout abs</body>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: cAnyPart size)
		addAll: cAnyPart;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	(super canUpdateForFrame: integer) ifFalse: [^false].
	cAnyPart 
		do: [:aAnyPart | (aAnyPart canUpdateForFrame: integer) ifFalse: [^false]].
	cConstraintSet 
		do: [:aConstraintSet | (aConstraintSet canUpdateForFrame: integer) ifFalse: [^false]].
	cForceTorque 
		do: [:aForceTorque | (aForceTorque canUpdateForFrame: integer) ifFalse: [^false]].
	^true</body>

<body package="CADSM-Geo" selector="isAssembly">isAssembly
	^true</body>

<body package="CADSM-Geo" selector="isValidAnyPart:">isValidAnyPart: aAnyPart 
	| nameList |
	(cAnyPart anySatisfy: [:aaAnyPart | aaAnyPart == aAnyPart]) 
		ifTrue: [^false].
	nameList := cAnyPart collect: [:aItem | aItem name].
	(aAnyPart name isNil or: [nameList includes: aAnyPart name asSymbol]) 
		ifTrue: 
			[| aString count newName |
			aString := aAnyPart class name.
			count := 0.
			
			[count := count + 1.
			newName := (aString , count printString) asSymbol.
			nameList includes: newName] 
					whileTrue.
			aAnyPart name: newName]
		ifFalse: [aAnyPart name: aAnyPart name asSymbol].
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAssembly</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="aFixedPart">aFixedPart
	^cAnyPart at: 1</body>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| aMbDUnits aMbDAssembly aSimulationData aMbDSystemSolver block |
	aMbDUnits := self aMbDUnits.
	aMbDAssembly := CADSMMbDAssembly new.
	self mbdObject: aMbDAssembly.
	aMbDAssembly name: self name.
	aMbDAssembly rFfF: self rFfF / aMbDUnits length.
	aMbDAssembly aAFf: self aAFf.
	aSup mbdObject addAssembly: aMbDAssembly.
	aSup isUniverse 
		ifTrue: 
			[self aGravity createMbD.
			self aGeoTime createMbD.
			self timesAtDiscontinuities: OrderedCollection new.
			aSimulationData := self aSimulationData.
			self timeSeries: OrderedCollection new.
			aMbDSystemSolver := self aMediator aMbDSolver.
			aMbDUnits := self aMbDUnits.
			aMbDSystemSolver errorTolPosKine: aSimulationData errorTolPosKine abs.
			aMbDSystemSolver errorTolAccKine: aSimulationData errorTolAccKine abs.
			aMbDSystemSolver iterMaxPosKine: aSimulationData iterMaxPosKine abs.
			aMbDSystemSolver iterMaxAccKine: aSimulationData iterMaxAccKine abs.
			aMbDSystemSolver tstart: aSimulationData tstart / aMbDUnits time.
			aMbDSystemSolver tend: aSimulationData tend / aMbDUnits time.
			aMbDSystemSolver hmin: aSimulationData hmin abs / aMbDUnits time.
			aMbDSystemSolver hmax: aSimulationData hmax abs / aMbDUnits time.
			aMbDSystemSolver hout: aSimulationData hout abs / aMbDUnits time.
			aMbDSystemSolver corAbsTol: aSimulationData corAbsTol abs.
			aMbDSystemSolver corRelTol: aSimulationData corRelTol abs.
			aMbDSystemSolver intAbsTol: aSimulationData intAbsTol abs.
			aMbDSystemSolver intRelTol: aSimulationData intRelTol abs.
			aMbDSystemSolver iterMaxDyn: aSimulationData iterMaxDyn abs.
			aMbDSystemSolver orderMax: aSimulationData orderMax abs.
			aMbDSystemSolver 
				translationLimit: aSimulationData translationLimit abs / aMbDUnits length.
			aMbDSystemSolver rotationLimit: aSimulationData rotationLimit abs]
		ifFalse: 
			[self gravity: nil.
			self aMbDUnits: nil.
			self aSimulationData: nil.
			self aGeoTime: nil.
			self timeSeries: nil.
			self timesAtDiscontinuities: nil.
			self forcesTorques: nil].
	self aAnimationData: nil.
	block := 
			[:collection | 
			(collection asSortedCollection: [:a :b | a name &lt;= b name]) 
				do: [:item | item createMbD]].
	block value: cAnyPart.
	block value: cConstraintSet.
	block value: self forcesTorques</body>

<body package="CADSM-Geo" selector="deleteMbD">deleteMbD
	super deleteMbD.
	self aGravity deleteMbD.
	self aGeoTime deleteMbD.
	cAnyPart do: [:item | item deleteMbD].
	cConstraintSet do: [:item | item deleteMbD].
	cForceTorque do: [:item | item deleteMbD]</body>

<body package="CADSM-Geo" selector="mass">mass
	^self aFixedPart mass</body>

<body package="CADSM-Geo" selector="mJpp">mJpp
	^self aFixedPart mJpp</body>

<body package="CADSM-Geo" selector="rOcmO">rOcmO
	^self aFixedPart rOcmO</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	super storeInputState.
	cAnyPart do: [:item | item storeInputState].
	cConstraintSet do: [:item | item storeInputState].
	cForceTorque do: [:item | item storeInputState]</body>

<body package="CADSM-Geo" selector="timesAtDiscontinuities:">timesAtDiscontinuities: timesAtDiscontinuities 
	self removeActionsForEvent: #timesAtDiscontinuities.
	timesAtDiscontinuities ifNotNil: 
			[self 
				when: #timesAtDiscontinuities
				ask: timesAtDiscontinuities
				perform: #yourself]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphSphJoint</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="distanceIJ">distanceIJ
	^distanceIJ</body>

<body package="CADSM-Geo" selector="distanceIJ:">distanceIJ: anObject
	distanceIJ := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphSphJoint</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream 
		storeLevel: level + 1
		title: 'distanceIJ'
		object: distanceIJ</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphSphJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDSphSphJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'SphSphJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurface</class-id> <category>bounds</category>

<body package="CADSM-Geo" selector="boundByCurve:">boundByCurve: aCurve 
	"
	rFpF = rFpF
	rFSF + aAFS*rSpS = rFCF + aAFC*rCpC
	rSpS = aAFST(rFCF - rFSF + aAFC*rCpC)
	"

	| aCurveRefFrame aAFST aAFC rFCFrFSF |
	aCurveRefFrame := aCurve aRefFrame.
	aAFST := aRefFrame aAFf transpose.
	aAFC := aCurveRefFrame aAFf.
	rFCFrFSF := aCurveRefFrame rFfF minusFullColumn: aRefFrame rFfF.
	aCurve cPoint do: 
			[:rCpC | 
			| rSpS |
			rSpS := aAFST 
						timesFullColumn: (rFCFrFSF plusFullColumn: (aAFC timesFullColumn: rCpC)).
			aBoundingBox expandToBound: rSpS]</body>

<body package="CADSM-Geo" selector="boundByEllipticArc:">boundByEllipticArc: aEllipticArc 
	self boundByCurve: aEllipticArc</body>

<body package="CADSM-Geo" selector="boundByLine:">boundByLine: aLine 
	self boundByCurve: aLine</body>

<body package="CADSM-Geo" selector="boundByNurbsCurve:">boundByNurbsCurve: aNurbsCurve 
	self boundByCurve: aNurbsCurve</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurface</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd:">condition_cuv: cuv pre_uvEnd: pre_uvend 
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="uvCurveOfCurve:">uvCurveOfCurve: aCurve 
	| glSurface cnPoint cnPointOn_uv |
	glSurface := self glSurface.
	cnPoint := aCurve nPoint: 32.
	cnPointOn_uv := cnPoint collect: 
					[:aPointXYZ | 
					| uvGuess |
					uvGuess := self uvOfPoint: aPointXYZ.
					glSurface uvOfPoint: aPointXYZ uvGuess: uvGuess].
	^(CADSMGeoNurbsCurve new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfCurve:preCurve:">uvCurveOfCurve: aCurve preCurve: preCurve 
	| cnPoint cnPointOn_uv pre_uvEnd |
	cnPoint := aCurve nPoint: 32.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	^(CADSMGeoNurbsCurve fromcDataPoint: cnPointOn_uv uDegree: 3)
		isSpatial: false;
		privateCalcBoundingBox;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:">uvCurveOfEllipticArc: aEllipticArc 
	^self uvCurveOfCurve: aEllipticArc</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:preCurve:">uvCurveOfEllipticArc: aEllipticArc preCurve: preCurve 
	^self uvCurveOfCurve: aEllipticArc preCurve: preCurve</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:">uvCurveOfLine: aLine 
	^self uvCurveOfCurve: aLine</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:preCurve:">uvCurveOfLine: aLine preCurve: preCurve 
	^self uvCurveOfCurve: aLine preCurve: preCurve</body>

<body package="CADSM-Geo" selector="uvCurveOfNurbsCurve:">uvCurveOfNurbsCurve: aNurbsCurve 
	^self uvCurveOfCurve: aNurbsCurve</body>

<body package="CADSM-Geo" selector="uvCurveOfNurbsCurve:preCurve:">uvCurveOfNurbsCurve: aNurbsCurve preCurve: preCurve 
	^self uvCurveOfCurve: aNurbsCurve preCurve: preCurve</body>

<body package="CADSM-Geo" selector="uvOfPoint:">uvOfPoint: rFpF 
	^self glSurface uvOfPoint: rFpF</body>

<body package="CADSM-Geo" selector="uvOfPoint:uvGuess:">uvOfPoint: rFpF uvGuess: uvGuess 
	^self uvOfPoint: rFpF</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="at_uv:">at_uv: uv 
	^self atu: uv first v: uv last</body>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs1:">condition_cglTrimNurbs1: cglTrimNurbs 
	"Do nothing."

	^cglTrimNurbs</body>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs:">condition_cglTrimNurbs: cglTrimNurbs 
	"Do nothing."

	^cglTrimNurbs</body>

<body package="CADSM-Geo" selector="finalize_uvCurve:">finalize_uvCurve: aaCurve 
	self condition_cuv: aaCurve.
	aaCurve finalize_cuv</body>

<body package="CADSM-Geo" selector="rFpF_u:v:">rFpF_u: u v: v 
	^aRefFrame rFpFfromrfpf: (self rfpf_u: u v: v)</body>

<body package="CADSM-Geo" selector="rfpf_u:v:">rfpf_u: u v: v 
	self subclassResponsibility</body>

<body package="CADSM-Geo" selector="rFpF_uv:">rFpF_uv: uv 
	^self rFpF_u: uv first v: uv last</body>

<body package="CADSM-Geo" selector="rfpf_uv:">rfpf_uv: uv 
	^self rfpf_u: uv first v: uv last</body>

<body package="CADSM-Geo" selector="uvBound">uvBound
	^CADSMMiscBoundingRectangle origin: (StMFullColumn zero: 2)
		corner: (StMFullColumn with: 1.0d with: 1.0d)</body>

<body package="CADSM-Geo" selector="uvBoundTol">uvBoundTol
	| tol umin vmin umax vmax |
	tol := 1.0d-6.
	umin := 0.0d.
	vmin := 0.0d.
	umax := 1.0d.
	vmax := 1.0d.
	^CADSMMiscBoundingRectangle 
		origin: (StMFullColumn with: umin - tol with: vmin - tol)
		corner: (StMFullColumn with: umax + tol with: vmax + tol)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="create_glSurface">create_glSurface
	^self create_glNurbs</body>

<body package="CADSM-Geo" selector="glSurface">glSurface
	^(self triggerEvent: #glSurface) ifNil: 
			[| answer |
			answer := self create_glSurface.
			self glSurface: answer.
			answer]</body>

<body package="CADSM-Geo" selector="glSurface:">glSurface: glSurface 
	self removeActionsForEvent: #glSurface.
	glSurface ifNotNil: 
			[self 
				when: #glSurface
				ask: glSurface
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="ruvBoundFrom:">ruvBoundFrom: gluvBound 
	| gluvmin gluvmax ruvmin ruvmax |
	gluvmin := gluvBound minCorner.
	gluvmax := gluvBound maxCorner.
	ruvmin := self uv_gluv: gluvmin.
	ruvmin u: ruvmin u + (gluvmin u - ruvmin u) rounded.
	ruvmin v: ruvmin v + (gluvmin v - ruvmin v) rounded.
	ruvmax := self uv_gluv: gluvmax.
	ruvmax u: ruvmax u + (gluvmax u - ruvmax u) rounded.
	ruvmax v: ruvmax v + (gluvmax v - ruvmax v) rounded.
	^CADSMMiscBoundingRectangle origin: ruvmin corner: ruvmax</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurface</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	self glSurface: nil.
	self aNurbs: nil</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSweep</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aCurve">aCurve
	^aCurve</body>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: 2)
		add: aCurve;
		add: trajectory;
		yourself</body>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsSurface fromSweep: self</body>

<body package="CADSM-Geo" selector="trajectory">trajectory
	^trajectory</body>

<body package="CADSM-Geo" selector="_aCurve:">_aCurve: aaCurve 
	aaCurve removeSup.
	super addRefFrame: aaCurve aRefFrame.
	aCurve := aaCurve.
	aaCurve aSup: self.
	^aaCurve</body>

<body package="CADSM-Geo" selector="_trajectory:">_trajectory: aaCurve 
	aaCurve removeSup.
	super addRefFrame: aaCurve aRefFrame.
	trajectory := aaCurve.
	aaCurve aSup: self.
	^aaCurve</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSweep</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="calc">calc
	"Make origin of be the origin of curve. Should move in xy plane only."

	| aCurveRefFrame newrFfF newAFf |
	aCurveRefFrame := aCurve aRefFrame.
	newrFfF := aRefFrame rFfF 
				+ (aRefFrame aAFf timesFullColumn: aCurveRefFrame rFfF).
	newAFf := aRefFrame aAFf timesFullMatrix: aCurveRefFrame aAFf.
	aRefFrame rFfF: newrFfF.
	aRefFrame aAFf: newAFf.
	aCurveRefFrame fixedAtRef.
	trajectory aRefFrame fixedAtRef</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSweep</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	aCurve magnifySelf: aDouble.
	trajectory magnifySelf: aDouble</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSweep</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="cEndSingularityOf:">cEndSingularityOf: aaCurve 
	^StMArray with: false with: false</body>

<body package="CADSM-Geo" selector="conditionSelf">conditionSelf
	(trajectory isMemberOf: CADSMGeoLine) 
		ifTrue: 
			[trajectory rfendf: (trajectory aDir normalized 
						magnifySelf: aBoundingBox diagonal_length)]</body>

<body package="CADSM-Geo" selector="condition_cLoopUse:within:">condition_cLoopUse: cLoopUse within: uvBound 
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	trajectory reverseSelf</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^CADSMGeoNurbsSurface fromSweep: self</body>

<body package="CADSM-Geo" selector="smooth_cuv:">smooth_cuv: uvCurve 
	"Do nothing."</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPlane</class-id> <category>accessing</category>

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

	argaRectSurface removeSup.
	super addRefFrame: argaRectSurface aRefFrame.
	aRectSurface := argaRectSurface.
	argaRectSurface aSup: self.
	self calcBoundingBox.
	^argaRectSurface</body>

<body package="CADSM-Geo" selector="aRectSurface">aRectSurface
	^aRectSurface</body>

<body package="CADSM-Geo" selector="aRectSurface:">aRectSurface: anObject
	aRectSurface := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPlane</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	self addRectSurface: CADSMGeoRectSurface new</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aNurbs">aNurbs
	^self</body>

<body package="CADSM-Geo" selector="atu:v:">atu: u v: v 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller. 
	pp 134.
	"

	| uSpan cNu vSpan cNv cNumerator cDenominator nDimension uSpanDegree vSpanDegree numerator denominator |
	uSpan := self uspan_at: u.
	cNu := self cNu_at: u uSpan: uSpan.
	vSpan := self vspan_at: v.
	cNv := self cNv_at: v vSpan: vSpan.
	cNumerator := StMFullColumn new: vDegree + 1.
	cDenominator := StMFullColumn new: vDegree + 1.
	nDimension := self nDimension.
	uSpanDegree := uSpan - uDegree.
	vSpanDegree := vSpan - vDegree.
	0 to: vDegree
		do: 
			[:j | 
			| j1 jj |
			j1 := j + 1.
			jj := vSpanDegree + j.
			cNumerator at: j1 put: (StMFullColumn zero: nDimension).
			cDenominator at: j1 put: 0.0d.
			0 to: uDegree
				do: 
					[:i | 
					| ii nuw |
					ii := uSpanDegree + i.
					nuw := (cNu at: i + 1) * (ccWeight at: ii and: jj).
					(cNumerator at: j1) equalSelfPlusFullColumn: (ccPoint at: ii and: jj)
						times: nuw.
					cDenominator at: j1 plusNumber: nuw]].
	numerator := StMFullColumn zero: nDimension.
	denominator := 0.0d.
	0 to: vDegree
		do: 
			[:j | 
			| j1 nv |
			j1 := j + 1.
			nv := cNv at: j1.
			numerator equalSelfPlusFullColumn: (cNumerator at: j1) times: nv.
			denominator := denominator + ((cDenominator at: j1) * nv)].
	^numerator / denominator</body>

<body package="CADSM-Geo" selector="ccPoint">ccPoint
	^ccPoint</body>

<body package="CADSM-Geo" selector="ccPoint:">ccPoint: anObject
	ccPoint := anObject</body>

<body package="CADSM-Geo" selector="ccWeight">ccWeight
	^ccWeight</body>

<body package="CADSM-Geo" selector="ccWeight:">ccWeight: anObject
	ccWeight := anObject</body>

<body package="CADSM-Geo" selector="cSingularity">cSingularity
	^cSingularity</body>

<body package="CADSM-Geo" selector="cSingularity:">cSingularity: anObject
	cSingularity := anObject</body>

<body package="CADSM-Geo" selector="cuKnot">cuKnot
	^cuKnot</body>

<body package="CADSM-Geo" selector="cuKnot:">cuKnot: anObject
	cuKnot := anObject</body>

<body package="CADSM-Geo" selector="cvKnot">cvKnot
	^cvKnot</body>

<body package="CADSM-Geo" selector="cvKnot:">cvKnot: anObject 
	cvKnot := anObject</body>

<body package="CADSM-Geo" selector="nDimension">nDimension
	^ccPoint first first size</body>

<body package="CADSM-Geo" selector="reverse">reverse
	| answer answercuKnot size answerccPoint nrow ncol |
	answer := self copy.
	answercuKnot := answer cuKnot.
	size := cuKnot size.
	1 to: size
		do: [:i | answercuKnot at: size - i + 1 put: (cuKnot at: i) negated].
	answerccPoint := answer ccPoint.
	nrow := ccPoint nrow.
	ncol := ccPoint ncol.
	1 to: nrow
		do: 
			[:i | 
			1 to: ncol
				do: 
					[:j | 
					answerccPoint 
						at: nrow - i + 1
						and: j
						put: (ccPoint at: i and: j)]].
	^answer</body>

<body package="CADSM-Geo" selector="rfpf_u:v:">rfpf_u: u v: v 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller. 
	pp 134.
	"

	| uSpan cNu vSpan cNv cNumerator cDenominator nDimension uSpanDegree vSpanDegree numerator denominator |
	uSpan := self uspan_at: u.
	cNu := self cNu_at: u uSpan: uSpan.
	vSpan := self vspan_at: v.
	cNv := self cNv_at: v vSpan: vSpan.
	cNumerator := StMFullColumn new: vDegree + 1.
	cDenominator := StMFullColumn new: vDegree + 1.
	nDimension := self nDimension.
	uSpanDegree := uSpan - uDegree.
	vSpanDegree := vSpan - vDegree.
	0 to: vDegree
		do: 
			[:j | 
			| j1 jj |
			j1 := j + 1.
			jj := vSpanDegree + j.
			cNumerator at: j1 put: (StMFullColumn zero: nDimension).
			cDenominator at: j1 put: 0.0d.
			0 to: uDegree
				do: 
					[:i | 
					| ii nuw |
					ii := uSpanDegree + i.
					nuw := (cNu at: i + 1) * (ccWeight at: ii and: jj).
					(cNumerator at: j1) equalSelfPlusFullColumn: (ccPoint at: ii and: jj)
						times: nuw.
					cDenominator at: j1 plusNumber: nuw]].
	numerator := StMFullColumn zero: nDimension.
	denominator := 0.0d.
	0 to: vDegree
		do: 
			[:j | 
			| j1 nv |
			j1 := j + 1.
			nv := cNv at: j1.
			numerator equalSelfPlusFullColumn: (cNumerator at: j1) times: nv.
			denominator := denominator + ((cDenominator at: j1) * nv)].
	^numerator / denominator</body>

<body package="CADSM-Geo" selector="show">show
	(self asJunOpenGL3dNurbsSurface)
		paint: ColorValue blue;
		show</body>

<body package="CADSM-Geo" selector="uDegree">uDegree
	^uDegree</body>

<body package="CADSM-Geo" selector="vDegree">vDegree
	^vDegree</body>

<body package="CADSM-Geo" selector="_ccPoint:">_ccPoint: accPoint 
	ccPoint := accPoint.
	self calc_ccSingularity.
	self calc_uDegree.
	self calc_vDegree</body>

<body package="CADSM-Geo" selector="_cuKnot:">_cuKnot: acuKnot 
	cuKnot := acuKnot.
	self calc_uDegree.
	umin := cuKnot first.
	umax := cuKnot last</body>

<body package="CADSM-Geo" selector="_cvKnot:">_cvKnot: acvKnot 
	cvKnot := acvKnot.
	self calc_vDegree.
	vmin := cvKnot first.
	vmax := cvKnot last</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="asJunOpenGL3dNurbsSurface">asJunOpenGL3dNurbsSurface
	^JunOpenGL3dNurbsSurface 
		controlPoints: ccPoint asJunMatrix
		weights: ccWeight asJunMatrix
		uKnotVector: cuKnot copy
		vKnotVector: cvKnot copy</body>

<body package="CADSM-Geo" selector="calc_ccSingularity">calc_ccSingularity
	| extend_length minPoint uminSingularity vminSingularity maxPoint umaxSingularity vmaxSingularity |
	cSingularity := CADSM.Misc.CADSMMiscOrderedSet new.
	extend_length := self extend_length.
	tolSingularity := 1.0d-4 * extend_length.
	minPoint := ccPoint at: 1 and: 1.
	uminSingularity := (ccPoint first 
				detect: [:aPoint | (aPoint - minPoint) length &gt;= tolSingularity]
				ifNone: nil) isNil.
	vminSingularity := (ccPoint 
				detect: [:cPoint | (cPoint first - minPoint) length &gt;= tolSingularity]
				ifNone: nil) isNil.
	uminSingularity ifTrue: [cSingularity add: minPoint].
	vminSingularity ifTrue: [cSingularity add: minPoint].
	maxPoint := ccPoint at: ccPoint nrow and: ccPoint ncol.
	umaxSingularity := (ccPoint last 
				detect: [:aPoint | (aPoint - maxPoint) length &gt;= tolSingularity]
				ifNone: nil) isNil.
	vmaxSingularity := (ccPoint 
				detect: [:cPoint | (cPoint last - maxPoint) length &gt;= tolSingularity]
				ifNone: nil) isNil.
	umaxSingularity ifTrue: [cSingularity add: maxPoint].
	vmaxSingularity ifTrue: [cSingularity add: maxPoint]</body>

<body package="CADSM-Geo" selector="calc_uDegree">calc_uDegree
	ccPoint 
		ifNotNil: [cuKnot ifNotNil: [uDegree := cuKnot size - ccPoint size - 1]]</body>

<body package="CADSM-Geo" selector="calc_vDegree">calc_vDegree
	ccPoint 
		ifNotNil: [cvKnot ifNotNil: [vDegree := cvKnot size - ccPoint first size - 1]]</body>

<body package="CADSM-Geo" selector="CcBinomial">CcBinomial
	^CADSMGeoNurbsCurve CcBinomial</body>

<body package="CADSM-Geo" selector="ccDeriv:u:v:">ccDeriv: iDeriv u: u v: v 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp. 111, 137
	"

	| iDeriv1 nDimension ccDeriv ccDerivP ccDerivW iDerivu iDerivv uSpan ccDerivNu vSpan ccDerivNv cNumerator cDenominator uSpanDegree vSpanDegree |
	iDeriv1 := iDeriv + 1.
	nDimension := self nDimension.
	ccDeriv := StMFullMatrix new: iDeriv1 by: iDeriv1.
	ccDerivP := StMFullMatrix new: iDeriv1 by: iDeriv1.
	ccDerivW := StMFullMatrix new: iDeriv1 by: iDeriv1.
	uDegree + 1 to: iDeriv
		do: 
			[:i | 
			| i1 |
			i1 := i + 1.
			0 to: iDeriv - i
				do: 
					[:j | 
					| j1 |
					j1 := j + 1.
					ccDeriv 
						at: i1
						and: j1
						put: (StMFullColumn zero: nDimension).
					ccDerivP 
						at: i1
						and: j1
						put: (StMFullColumn zero: nDimension).
					ccDerivW 
						at: i1
						and: j1
						put: 0.0d]].
	vDegree + 1 to: iDeriv
		do: 
			[:i | 
			| i1 |
			i1 := i + 1.
			0 to: iDeriv - i
				do: 
					[:j | 
					| j1 |
					j1 := j + 1.
					ccDeriv 
						at: j1
						and: i1
						put: (StMFullColumn zero: nDimension).
					ccDerivP 
						at: j1
						and: i1
						put: (StMFullColumn zero: nDimension).
					ccDerivW 
						at: j1
						and: i1
						put: 0.0d]].
	iDerivu := iDeriv min: uDegree.
	iDerivv := iDeriv min: vDegree.
	uSpan := self uspan_at: u.
	ccDerivNu := CADSMGeoNurbsCurve 
				ccDerivNu_at: u
				uDeriv: iDerivu
				uSpan: uSpan
				cuKnot: cuKnot
				uDegree: uDegree.
	vSpan := self vspan_at: v.
	ccDerivNv := CADSMGeoNurbsCurve 
				ccDerivNu_at: v
				uDeriv: iDerivv
				uSpan: vSpan
				cuKnot: cvKnot
				uDegree: vDegree.
	cNumerator := StMFullColumn new: vDegree + 1.
	cDenominator := StMFullColumn new: vDegree + 1.
	uSpanDegree := uSpan - uDegree.
	vSpanDegree := vSpan - vDegree.
	0 to: iDerivu
		do: 
			[:i | 
			| i1 iDerivuv |
			i1 := i + 1.
			0 to: vDegree
				do: 
					[:j | 
					| j1 jj |
					j1 := j + 1.
					cNumerator at: j1 put: (StMFullColumn zero: nDimension).
					cDenominator at: j1 put: 0.0d.
					jj := vSpanDegree + j.
					0 to: uDegree
						do: 
							[:k | 
							| k1 kk ccDerivNuw |
							k1 := k + 1.
							kk := uSpanDegree + k.
							ccDerivNuw := (ccDerivNu at: i1 and: k1) * (ccWeight at: kk and: jj).
							(cNumerator at: j1) equalSelfPlusFullColumn: (ccPoint at: kk and: jj)
								times: ccDerivNuw.
							cDenominator at: j1 plusNumber: ccDerivNuw]].
			iDerivuv := iDeriv - i min: iDerivv.
			0 to: iDerivuv
				do: 
					[:j | 
					| j1 |
					j1 := j + 1.
					ccDerivP 
						at: i1
						and: j1
						put: (StMFullColumn zero: nDimension).
					ccDerivW 
						at: i1
						and: j1
						put: 0.0d.
					0 to: vDegree
						do: 
							[:k | 
							| k1 ccDerivNv1 |
							k1 := k + 1.
							ccDerivNv1 := ccDerivNv at: j1 and: k1.
							(ccDerivP at: i1 and: j1) equalSelfPlusFullColumn: (cNumerator at: k1)
								times: ccDerivNv1.
							ccDerivW 
								at: i1
								and: j1
								plusNumber: ccDerivNv1 * (cDenominator at: k1)]]].
	0 to: iDeriv
		do: 
			[:i | 
			| i1 |
			i1 := i + 1.
			0 to: iDeriv - i
				do: 
					[:j | 
					| j1 temp |
					j1 := j + 1.
					temp := ccDerivP at: i1 and: j1.
					1 to: j
						do: 
							[:k | 
							| k1 jk1 bw |
							k1 := k + 1.
							jk1 := j - k + 1.
							bw := ((self CcBinomial at: j1) at: k1) negated * (ccDerivW at: 1 and: k1).
							temp equalSelfPlusFullColumn: (ccDeriv at: i1 and: jk1) times: bw].
					1 to: i
						do: 
							[:k | 
							| k1 ik1 bw temp2 |
							k1 := k + 1.
							ik1 := i - k + 1.
							bw := ((self CcBinomial at: i1) at: k1) negated * (ccDerivW at: k1 and: 1).
							temp equalSelfPlusFullColumn: (ccDeriv at: ik1 and: j1) times: bw.
							temp2 := StMFullColumn zero: nDimension.
							1 to: j
								do: 
									[:l | 
									| l1 jl1 |
									l1 := l + 1.
									jl1 := j - l + 1.
									bw := ((self CcBinomial at: j1) at: l1) * (ccDerivW at: k1 and: l1).
									temp2 equalSelfPlusFullColumn: (ccDeriv at: ik1 and: jl1) times: bw].
							temp equalSelfPlusFullColumn: temp2
								times: ((self CcBinomial at: i1) at: k1) negated].
					ccDeriv 
						at: i1
						and: j1
						put: temp / (ccDerivW at: 1 and: 1)]].
	^ccDeriv</body>

<body package="CADSM-Geo" selector="cEndSingularityOf:">cEndSingularityOf: aCurve 
	"Singularities occur at ends. Extrapolate the first or last point if necessary."

	| cuv cuv1 cuvn startInterval endInterval block startSingularity endSingularity |
	cuv := aCurve cuv.
	cuv1 := cuv first copy.
	cuvn := cuv last copy.
	startInterval := 1 to: 3.
	endInterval := cuv size to: cuv size - 2 by: -1.
	block := 
			[:aInterval | 
			| uv3 uv2 uv1 largeDummy du2 du1 tol u1 v1 |
			uv3 := cuv at: (aInterval at: 3).
			uv2 := cuv at: (aInterval at: 2).
			uv1 := cuv at: (aInterval at: 1).
			uv1 ifNil: 
					[largeDummy := 1.0d3.
					uv1 := StMFullColumn with: largeDummy with: largeDummy.
					cuv at: (aInterval at: 1) put: uv1].
			du2 := uv2 - uv3.
			du1 := uv1 - uv2.
			tol := 0.5d * du2 length.
			(du2 - du1) length &gt;= tol 
				ifTrue: 
					[u1 := uv2 u + du2 u.
					v1 := uv2 v + du2 v.
					uv1 u: u1.
					uv1 v: v1]].
	block value: startInterval.
	block value: endInterval.
	startSingularity := (cuv1 = cuv first) not.
	endSingularity := (cuvn = cuv last) not.
	^StMArray with: startSingularity with: endSingularity</body>

<body package="CADSM-Geo" selector="cNu_at:uSpan:">cNu_at: u uSpan: uSpan 
	^CADSMGeoNurbsCurve 
		cNu_at: u
		uSpan: uSpan
		cuKnot: cuKnot
		uDegree: uDegree</body>

<body package="CADSM-Geo" selector="cNv_at:vSpan:">cNv_at: v vSpan: vSpan 
	^CADSMGeoNurbsCurve 
		cNu_at: v
		uSpan: vSpan
		cuKnot: cvKnot
		uDegree: vDegree</body>

<body package="CADSM-Geo" selector="conditionEnd_cuv:pre_uvEnd:">conditionEnd_cuv: cuv pre_uvEnd: pre_uvend 
	"Singularities occur at ends. Extrapolate the first or last point if necessary."

	| cuv1 startInterval endInterval block |
	cuv1 := cuv first copy.
	startInterval := 1 to: 3.
	endInterval := cuv size to: cuv size - 2 by: -1.
	block := 
			[:aInterval | 
			| uv3 uv2 uv1 largeDummy du2 du1 tol u1 v1 |
			uv3 := cuv at: (aInterval at: 3).
			uv2 := cuv at: (aInterval at: 2).
			uv1 := cuv at: (aInterval at: 1).
			uv1 ifNil: 
					[largeDummy := 1.0d3.
					uv1 := StMFullColumn with: largeDummy with: largeDummy.
					cuv at: (aInterval at: 1) put: uv1].
			du2 := uv2 - uv3.
			du1 := uv1 - uv2.
			tol := 0.5d * du2 length.
			(du2 - du1) length &gt;= tol 
				ifTrue: 
					[u1 := uv2 u + du2 u.
					v1 := uv2 v + du2 v.
					uv1 u: u1.
					uv1 v: v1]].
	block value: startInterval.
	block value: endInterval.
	^cuv1 = cuv first 
		ifTrue: [pre_uvend]
		ifFalse: 
			["Discontinuity expected."

			nil]</body>

<body package="CADSM-Geo" selector="conditionOpenGL">conditionOpenGL
	| tol |
	tol := 1.0d-9.
	ccPoint conditionSelfWithTol: tol.
	ccWeight conditionSelfWithTol: tol.
	cuKnot conditionSelfWithTol: tol.
	cvKnot conditionSelfWithTol: tol</body>

<body package="CADSM-Geo" selector="conditionOpenGL1">conditionOpenGL1
	| tol |
	tol := 1.0d-9.
	ccPoint conditionSelfWithTol: tol.
	ccWeight conditionSelfWithTol: tol.
	cuKnot conditionSelfWithTol: tol.
	cvKnot conditionSelfWithTol: tol</body>

<body package="CADSM-Geo" selector="conditionOpenGL2">conditionOpenGL2
	| tol magnification |
	tol := 1.0d-9.
	ccPoint conditionSelfWithTol: tol.
	ccWeight conditionSelfWithTol: tol.
	cuKnot conditionSelfWithTol: tol.
	cvKnot conditionSelfWithTol: tol.
	magnification := 1.0d / (umax - umin).
	cuKnot := cuKnot collect: [:u | (u - umin) * magnification].
	umin := 0.0d.
	umax := 1.0d.
	magnification := 1.0d / (vmax - vmin).
	cvKnot := cvKnot collect: [:v | (v - vmin) * magnification].
	vmin := 0.0d.
	vmax := 1.0d</body>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs1:">condition_cglTrimNurbs1: cglTrimNurbs 
	| tol aStream uvStart uvNext uvStarti |
	tol := 1.0d-6.
	aStream := (cglTrimNurbs species new: cglTrimNurbs size) writeStream.
	uvStart := cglTrimNurbs first uvStart.
	uvNext := uvStart.
	cglTrimNurbs do: 
			[:glTrimNurbs | 
			uvStarti := glTrimNurbs uvStart.
			(uvNext - uvStarti) length &lt; tol 
				ifFalse: 
					[self name: #debug.
					aStream nextPut: (CADSMGeoNurbsCurve fromStart: uvNext copy toEnd: uvStarti copy)].
			aStream nextPut: glTrimNurbs.
			uvNext := glTrimNurbs uvEnd].
	(uvNext - uvStart) length &lt; tol 
		ifFalse: 
			[self name: #debug.
			aStream nextPut: (CADSMGeoNurbsCurve fromStart: uvNext copy toEnd: uvStart copy)].
	^aStream contents</body>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs:">condition_cglTrimNurbs: cglTrimNurbs 
	| tol aStream uvStart uvNext uvStarti |
	tol := 1.0d-4.
	aStream := (cglTrimNurbs species new: cglTrimNurbs size) writeStream.
	uvStart := cglTrimNurbs first uvStart.
	uvNext := uvStart.
	cglTrimNurbs do: 
			[:glTrimNurbs | 
			uvStarti := glTrimNurbs uvStart.
			(uvNext - uvStarti) length &lt; tol 
				ifFalse: 
					[self name: #debug.
					aStream nextPut: (CADSMGeoNurbsCurve 
								fromStart: uvNext copy
								toEnd: uvStarti copy
								isSpatial: false)].
			aStream nextPut: glTrimNurbs.
			uvNext := glTrimNurbs uvEnd].
	(uvNext - uvStart) length &lt; tol 
		ifFalse: 
			[self name: #debug.
			aStream nextPut: (CADSMGeoNurbsCurve 
						fromStart: uvNext copy
						toEnd: uvStart copy
						isSpatial: false)].
	^aStream contents</body>

<body package="CADSM-Geo" selector="condition_cLoopUse:within:">condition_cLoopUse: cLoopUse within: uvBound 
	"Scale uv values to fit within umin, umax, vmin, vmax."

	| uumin uumax uscale vvmin vvmax vscale |
	uumin := uvBound umin.
	uumax := uvBound umax.
	umin &lt; uumin ifTrue: [uumin := umin].
	umax &gt; uumax ifTrue: [uumax := umax].
	uscale := (umax - umin) / (uumax - uumin).
	vvmin := uvBound vmin.
	vvmax := uvBound vmax.
	vmin &lt; vvmin ifTrue: [vvmin := vmin].
	vmax &gt; vvmax ifTrue: [vvmax := vmax].
	vscale := (vmax - vmin) / (vvmax - vvmin).
	uscale &lt; 1.0d 
		ifTrue: 
			[vscale &lt; 1.0d 
				ifTrue: 
					[cLoopUse do: 
							[:aLoopUse | 
							aLoopUse ccuv do: 
									[:cuv | 
									cuv do: 
											[:uv | 
											uv u: (uv u - uumin) * uscale + umin.
											uv v: (uv v - vvmin) * vscale + vmin]]]]
				ifFalse: 
					[cLoopUse do: 
							[:aLoopUse | 
							aLoopUse ccuv 
								do: [:cuv | cuv do: [:uv | uv u: (uv u - uumin) * uscale + umin]]]]]
		ifFalse: 
			[vscale &lt; 1.0d 
				ifTrue: 
					[cLoopUse do: 
							[:aLoopUse | 
							aLoopUse ccuv 
								do: [:cuv | cuv do: [:uv | uv v: (uv v - vvmin) * vscale + vmin]]]]]</body>

<body package="CADSM-Geo" selector="condition_cuv1:">condition_cuv1: aCurve 
	| utol umin2 umax2 vtol vmin2 vmax2 |
	utol := 1.0d-3 * (umax - umin).
	umin2 := umin + utol.
	umax2 := umax - utol.
	vtol := 1.0d-3 * (vmax - vmin).
	vmin2 := vmin + vtol.
	vmax2 := vmax - vtol.
	aCurve cuv do: 
			[:uv | 
			uv at: 1
				put: ((uv at: 1) 
						conditionEqual: umin
						or_ge: umin2
						and_le: umax2
						orEqual: umax).
			uv at: 2
				put: ((uv at: 2) 
						conditionEqual: vmin
						or_ge: vmin2
						and_le: vmax2
						orEqual: vmax)]</body>

<body package="CADSM-Geo" selector="condition_cuv2:">condition_cuv2: aCurve 
	| uumin uumax vvmin vvmax cuv u v uscale vscale |
	uumin := StMMachineAccuracy OfLargestDouble.
	uumax := StMMachineAccuracy OfLargestDouble negated.
	vvmin := StMMachineAccuracy OfLargestDouble.
	vvmax := StMMachineAccuracy OfLargestDouble negated.
	cuv := aCurve cuv.
	cuv do: 
			[:uv | 
			u := uv at: 1.
			v := uv at: 2.
			uumin := uumin min: u.
			uumax := uumax max: u.
			vvmin := vvmin min: v.
			vvmax := vvmax max: v].
	umin &lt; uumin ifTrue: [uumin := umin].
	umax &gt; uumax ifTrue: [uumax := umax].
	uscale := (umax - umin) / (uumax - uumin).
	vmin &lt; vvmin ifTrue: [vvmin := vmin].
	vmax &gt; vvmax ifTrue: [vvmax := vmax].
	vscale := (vmax - vmin) / (vvmax - vvmin).
	uscale &lt; 1.0d 
		ifTrue: 
			[vscale &lt; 1.0d 
				ifTrue: 
					[cuv do: 
							[:uv | 
							uv u: (uv u - uumin) * uscale + umin.
							uv v: (uv v - vvmin) * vscale + vmin]]
				ifFalse: [cuv do: [:uv | uv u: (uv u - uumin) * uscale + umin]]]
		ifFalse: 
			[vscale &lt; 1.0d 
				ifTrue: [cuv do: [:uv | uv v: (uv v - vvmin) * vscale + vmin]]]</body>

<body package="CADSM-Geo" selector="condition_cuv3:">condition_cuv3: aCurve 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="condition_cuv:">condition_cuv: aCurve 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd:">condition_cuv: cuv pre_uvEnd: pre_uvend 
	| new_pre_uvend utol umin2 umax2 vtol vmin2 vmax2 cuv1 |
	new_pre_uvend := self conditionEnd_cuv: cuv pre_uvEnd: pre_uvend.
	utol := 1.0d-3 * (umax - umin).
	umin2 := umin + utol.
	umax2 := umax - utol.
	vtol := 1.0d-3 * (vmax - vmin).
	vmin2 := vmin + vtol.
	vmax2 := vmax - vtol.
	cuv do: 
			[:uv | 
			uv at: 1
				put: ((uv at: 1) 
						conditionEqual: umin
						or_ge: umin2
						and_le: umax2
						orEqual: umax).
			uv at: 2
				put: ((uv at: 2) 
						conditionEqual: vmin
						or_ge: vmin2
						and_le: vmax2
						orEqual: vmax)].
	new_pre_uvend ifNotNil: 
			[cuv1 := cuv first.
			self assert: 
					[| tol |
					tol := 1.0d-6.
					(new_pre_uvend - cuv1) length &lt; tol].
			cuv1 u: pre_uvend u.
			cuv1 v: pre_uvend v]</body>

<body package="CADSM-Geo" selector="condition_cuv:within:">condition_cuv: aaCurve within: aaBoundingRectangle 
	^self uvBound</body>

<body package="CADSM-Geo" selector="controlPointAtU:v:">controlPointAtU: u v: v 
	^ccPoint at: u and: v</body>

<body package="CADSM-Geo" selector="cuvGuess">cuvGuess
	| m n du dv cuvGuess |
	m := ccPoint size.
	n := ccPoint first size.
	du := (umax - umin) / (m - 1).
	dv := (vmax - vmin) / (n - 1).
	cuvGuess := OrderedCollection new: n * n.
	1 to: m
		do: 
			[:i | 
			| u |
			u := umin + ((i - 1) * du).
			1 to: n
				do: 
					[:j | 
					| v |
					v := vmin + ((j - 1) * dv).
					cuvGuess add: (u yd: v)]].
	^cuvGuess</body>

<body package="CADSM-Geo" selector="cuvGuess1">cuvGuess1
	| n du dv cuvGuess |
	n := 9.
	du := (umax - umin) / (n - 1).
	dv := (vmax - vmin) / (n - 1).
	cuvGuess := OrderedCollection new: n * n.
	1 to: n
		do: 
			[:i | 
			| u |
			u := umin + ((i - 1) * du).
			1 to: n
				do: 
					[:j | 
					| v |
					v := vmin + ((j - 1) * dv).
					cuvGuess add: (u yd: v)]].
	^cuvGuess</body>

<body package="CADSM-Geo" selector="extend_length">extend_length
	| aBBox ncol |
	aBBox := CADSM.Misc.CADSMMiscBoundingBox new.
	ncol := ccPoint ncol.
	1 to: ccPoint nrow
		do: 
			[:i | 
			| rowi |
			rowi := ccPoint at: i.
			1 to: ncol do: [:j | aBBox expandToBound: (rowi at: j)]].
	^aBBox diagonal_length</body>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	ccPoint magnifySelf: aDouble</body>

<body package="CADSM-Geo" selector="normalizeKnots">normalizeKnots
	| magnification |
	magnification := 1.0d / (umax - umin).
	cuKnot := cuKnot collect: [:u | (u - umin) * magnification].
	umin := 0.0d.
	umax := 1.0d.
	magnification := 1.0d / (vmax - vmin).
	cvKnot := cvKnot collect: [:v | (v - vmin) * magnification].
	vmin := 0.0d.
	vmax := 1.0d</body>

<body package="CADSM-Geo" selector="partialu:partialv:u:v:">partialu: uDeriv partialv: vDeriv u: u v: v 
	| ccDeriv |
	ccDeriv := self 
				ccDeriv: uDeriv + vDeriv
				u: u
				v: v.
	^ccDeriv at: uDeriv + 1 and: vDeriv + 1</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	cSingularity := nil.
	tolSingularity := nil.
	self _ccPoint: ccPoint reverse.
	self ccWeight: ccWeight reverse.
	self _cuKnot: cuKnot negated reverse</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^self copy</body>

<body package="CADSM-Geo" selector="smooth_cuv:">smooth_cuv: aCurve 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="smooth_cuv:within:">smooth_cuv: aCurve within: uvBound 
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="standardDeviation">standardDeviation
	| n ncol sum ssq |
	n := ccPoint numberOfElements.
	ncol := ccPoint ncol.
	sum := ssq := 0.0d.
	1 to: ccPoint nrow
		do: 
			[:i | 
			| rowi |
			rowi := ccPoint at: i.
			1 to: ncol
				do: 
					[:j | 
					| lengthsq length |
					lengthsq := (rowi at: j) sumOfSquaresOfVector.
					length := lengthsq sqrt.
					sum := sum + length.
					ssq := ssq + lengthsq]].
	^((n * ssq - (sum * sum)) / (n * n)) sqrt</body>

<body package="CADSM-Geo" selector="transformSelfBy_rFfF:aAFf:">transformSelfBy_rFfF: rFfF aAFf: aAFf 
	self 
		_ccPoint: (ccPoint collect: 
					[:cPoint | 
					cPoint 
						collect: [:aPoint | rFfF plusFullColumn: (aAFf timesFullColumn: aPoint)]])</body>

<body package="CADSM-Geo" selector="uKnotVector">uKnotVector
	^cuKnot</body>

<body package="CADSM-Geo" selector="uOrder">uOrder
	^cuKnot size - self uSize</body>

<body package="CADSM-Geo" selector="uSize">uSize
	^ccPoint nrow</body>

<body package="CADSM-Geo" selector="uspan_at:">uspan_at: u 
	^CADSMGeoNurbsCurve 
		uSpan_at: u
		cuKnot: cuKnot
		uDegree: uDegree</body>

<body package="CADSM-Geo" selector="uvBound">uvBound
	^CADSMMiscBoundingRectangle origin: (StMFullColumn with: umin with: vmin)
		corner: (StMFullColumn with: umax with: vmax)</body>

<body package="CADSM-Geo" selector="uvBoundTol">uvBoundTol
	| tol |
	tol := 1.0d-6.
	^CADSMMiscBoundingRectangle 
		origin: (StMFullColumn with: umin - tol with: vmin - tol)
		corner: (StMFullColumn with: umax + tol with: vmax + tol)</body>

<body package="CADSM-Geo" selector="uvCurveOfCurve1:">uvCurveOfCurve1: aCurve 
	"Since singularities occur at ends, solve from middle out to the ends."

	| n cnPoint cnPointOn_uv countdown countup block |
	n := 32.
	cnPoint := aCurve nPoint: n.
	cnPointOn_uv := cnPoint copyEmpty: n.
	countdown := n // 2 to: 1 by: -1.
	countup := n // 2 + 1 to: n.
	block := 
			[:interval | 
			| ii uvGuess uvGuessPrevious |
			ii := interval at: 1.
			uvGuessPrevious := self uvOfPoint: (cnPoint at: ii).
			cnPointOn_uv at: ii put: uvGuessPrevious.
			ii := interval at: 2.
			uvGuess := self uvOfPoint: (cnPoint at: ii) uvGuess: uvGuessPrevious.
			cnPointOn_uv at: ii put: uvGuess.
			3 to: interval size
				do: 
					[:i | 
					| aPointXYZ uvGuessNew |
					ii := interval at: i.
					aPointXYZ := cnPoint at: ii.
					uvGuessNew := uvGuess + (uvGuess - uvGuessPrevious).
					uvGuessNew u: (uvGuessNew u condition_ge: umin le: umax).
					uvGuessNew v: (uvGuessNew v condition_ge: vmin le: vmax).
					uvGuessPrevious := uvGuess.
					uvGuess := self uvOfPoint: aPointXYZ uvGuess: uvGuessNew.
					cnPointOn_uv at: ii put: uvGuess]].
	block value: countdown.
	block value: countup.
	^(CADSMGeoNurbsCurve new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfCurve:">uvCurveOfCurve: aCurve 
	"Since singularities occur at ends, solve from middle out to the ends."

	| n cnPoint cnPointOn_uv countdown countup block |
	n := 32.
	cnPoint := aCurve nPoint: n.
	cnPointOn_uv := cnPoint copyEmpty: n.
	countdown := n // 2 to: 1 by: -1.
	countup := n // 2 + 1 to: n.
	block := 
			[:interval | 
			| ii uvGuess uvGuessPrevious |
			ii := interval at: 1.
			uvGuessPrevious := self uvOfPoint: (cnPoint at: ii).
			cnPointOn_uv at: ii put: uvGuessPrevious.
			ii := interval at: 2.
			uvGuess := self uvOfPoint: (cnPoint at: ii) uvGuess: uvGuessPrevious.
			cnPointOn_uv at: ii put: uvGuess.
			3 to: interval size
				do: 
					[:i | 
					| aPointXYZ uvGuessNew |
					ii := interval at: i.
					aPointXYZ := cnPoint at: ii.
					uvGuessNew := uvGuess + (uvGuess - uvGuessPrevious).
					uvGuessNew u: (uvGuessNew u condition_ge: umin le: umax).
					uvGuessNew v: (uvGuessNew v condition_ge: vmin le: vmax).
					uvGuessPrevious := uvGuess.
					uvGuess := self uvOfPoint: aPointXYZ uvGuess: uvGuessNew.
					cnPointOn_uv at: ii put: uvGuess]].
	block value: countdown.
	block value: countup.
	^(CADSMGeoNurbsCurve new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfCurve:preCurve1:">uvCurveOfCurve: aCurve preCurve1: preCurve 
	| n cnPoint cnPointOn_uv uvGuess interval pre_uvEnd |
	n := 32.
	cnPoint := aCurve nPoint: n.
	cnPointOn_uv := cnPoint copyEmpty: n.
	uvGuess := self uvOfPoint: cnPoint first.
	interval := uvGuess ifNil: [n to: 1 by: -1] ifNotNil: [1 to: n].
	interval do: 
			[:i | 
			| aPointXYZ |
			aPointXYZ := cnPoint at: i.
			uvGuess := uvGuess ifNil: [self uvOfPoint: aPointXYZ]
						ifNotNil: [self uvOfPoint: aPointXYZ uvGuess: uvGuess].
			cnPointOn_uv at: i put: uvGuess].
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	^(CADSMGeoNurbsCurve fromcDataPoint: cnPointOn_uv uDegree: 3)
		isSpatial: false;
		privateCalcBoundingBox;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfCurve:preCurve:">uvCurveOfCurve: aCurve preCurve: preCurve 
	"Since singularities occur at ends, solve from middle out to the ends."

	| n cnPoint cnPointOn_uv countdown countup block pre_uvEnd |
	n := 32.
	cnPoint := aCurve nPoint: n.
	cnPointOn_uv := cnPoint copyEmpty: n.
	countdown := n // 2 to: 1 by: -1.
	countup := n // 2 + 1 to: n.
	block := 
			[:interval | 
			| ii uvGuess uvGuessPrevious |
			ii := interval at: 1.
			uvGuessPrevious := self uvOfPoint: (cnPoint at: ii).
			cnPointOn_uv at: ii put: uvGuessPrevious.
			ii := interval at: 2.
			uvGuess := self uvOfPoint: (cnPoint at: ii) uvGuess: uvGuessPrevious.
			cnPointOn_uv at: ii put: uvGuess.
			3 to: interval size
				do: 
					[:i | 
					| aPointXYZ uvGuessNew |
					ii := interval at: i.
					aPointXYZ := cnPoint at: ii.
					uvGuessNew := uvGuess + (uvGuess - uvGuessPrevious).
					uvGuessNew u: (uvGuessNew u condition_ge: umin le: umax).
					uvGuessNew v: (uvGuessNew v condition_ge: vmin le: vmax).
					uvGuessPrevious := uvGuess.
					uvGuess := self uvOfPoint: aPointXYZ uvGuess: uvGuessNew.
					cnPointOn_uv at: ii put: uvGuess]].
	block value: countdown.
	block value: countup.
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	^(CADSMGeoNurbsCurve fromcDataPoint: cnPointOn_uv uDegree: 3)
		isSpatial: false;
		privateCalcBoundingBox;
		yourself</body>

<body package="CADSM-Geo" selector="uvOfPoint:">uvOfPoint: rFpF 
	| dist newdist uvGuess tol |
	cSingularity 
		do: [:aSingularity | (rFpF - aSingularity) length &lt; tolSingularity ifTrue: [^nil]].
	dist := StMMachineAccuracy OfLargestDouble.
	self cuvGuess do: 
			[:aGuess | 
			newdist := (rFpF minusFullColumn: (self at_uv: aGuess)) length.
			newdist &lt; dist 
				ifTrue: 
					[dist := newdist.
					uvGuess := aGuess]].
	tol := 1.0d-6 * aBoundingBox diagonal_length.
	^dist &lt; tol 
		ifTrue: [uvGuess]
		ifFalse: [self uvOfPoint: rFpF uvGuess: uvGuess]</body>

<body package="CADSM-Geo" selector="uvOfPoint:uvGuess:">uvOfPoint: rFpF uvGuess: uvGuess 
	cSingularity 
		do: [:aSingularity | (rFpF - aSingularity) length &lt; tolSingularity ifTrue: [^nil]].
	^(NurbsSurfaceInversion new)
		rFpF: rFpF;
		x: uvGuess;
		system: self;
		run;
		x</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound:">uvShiftToFituvBound: uvBound 
	^(self uvBoundTol contains: uvBound) 
		ifTrue: [nil]
		ifFalse: 
			[self assert: 
					[self toTranscriptShow: uvBound.
					true].
			nil]</body>

<body package="CADSM-Geo" selector="vKnotVector">vKnotVector
	^cvKnot</body>

<body package="CADSM-Geo" selector="vOrder">vOrder
	^cvKnot size - self vSize</body>

<body package="CADSM-Geo" selector="vSize">vSize
	^ccPoint ncol</body>

<body package="CADSM-Geo" selector="vspan_at:">vspan_at: v 
	^CADSMGeoNurbsCurve 
		uSpan_at: v
		cuKnot: cvKnot
		uDegree: vDegree</body>

<body package="CADSM-Geo" selector="weightAtU:v:">weightAtU: u v: v 
	^ccWeight at: u and: v</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	ccPoint := ccPoint copy.
	ccWeight := ccWeight copy.
	cuKnot := cuKnot copy.
	cvKnot := cvKnot copy</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox new.
	ccPoint 
		do: [:cPoint | cPoint do: [:aPoint | aBoundingBox expandToBound: aPoint]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface class</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="fromRectSurface:">fromRectSurface: aRectSurface 
	| answer ccPoint ccWeight cuKnot umin umax cvKnot vmin vmax |
	answer := self new.
	ccPoint := StMFullMatrix new: 2 by: 2.
	ccPoint 
		at: 1
		and: 1
		put: aRectSurface minxminyminz.
	ccPoint 
		at: 1
		and: 2
		put: aRectSurface minxmaxyminz.
	ccPoint 
		at: 2
		and: 1
		put: aRectSurface maxxminyminz.
	ccPoint 
		at: 2
		and: 2
		put: aRectSurface maxxmaxyminz.
	ccPoint do: [:cPoint | cPoint do: [:aPoint | aPoint z: 0.0d]].
	answer _ccPoint: ccPoint.
	ccWeight := StMFullMatrix new: 2 by: 2.
	ccWeight do: [:cWeight | cWeight atAllPut: 1.0d].
	answer ccWeight: ccWeight.
	cuKnot := Array new: 4.
	umin := 0.0d.
	umax := 1.0d.
	cuKnot at: 1 put: umin.
	cuKnot at: 2 put: umin.
	cuKnot at: 3 put: umax.
	cuKnot at: 4 put: umax.
	cvKnot := Array new: 4.
	vmin := 0.0d.
	vmax := 1.0d.
	cvKnot at: 1 put: vmin.
	cvKnot at: 2 put: vmin.
	cvKnot at: 3 put: vmax.
	cvKnot at: 4 put: vmax.
	answer _cuKnot: cuKnot.
	answer _cvKnot: cvKnot.
	^answer</body>

<body package="CADSM-Geo" selector="fromSolidOfRevolution:">fromSolidOfRevolution: aSolidOfRevolution 
	| answer aCircleNurbs aCurveNurbs aCirclecPoint aCurvecPoint aCirclecWeight aCurvecWeight m n cRadius cHeight ccPoint ccWeight |
	answer := self new.
	aCircleNurbs := (CADSM.Geo.CADSMGeoCircle new)
				_radius: 1.0d;
				aNurbs.
	aCurveNurbs := aSolidOfRevolution aCurve rFpFNurbs.
	aCirclecPoint := aCircleNurbs cPoint.
	aCurvecPoint := aCurveNurbs cPoint.
	aCirclecWeight := aCircleNurbs cWeight.
	aCurvecWeight := aCurveNurbs cWeight.
	m := aCirclecPoint size.
	n := aCurvecPoint size.
	cRadius := aCurvecPoint shallowCopy.
	cHeight := aCurvecPoint shallowCopy.
	1 to: n
		do: 
			[:j | 
			| aCurvecPointj |
			aCurvecPointj := aCurvecPoint at: j.
			cRadius at: j put: aCurvecPointj x.
			cHeight at: j put: aCurvecPointj z].
	ccPoint := StMFullMatrix new: m by: n.
	ccWeight := StMFullMatrix new: m by: n.
	1 to: m
		do: 
			[:i | 
			| aCirclecPointi aCirclecWeighti ccPointi ccWeighti |
			aCirclecPointi := aCirclecPoint at: i.
			aCirclecWeighti := aCirclecWeight at: i.
			ccPointi := ccPoint at: i.
			ccWeighti := ccWeight at: i.
			1 to: n
				do: 
					[:j | 
					| xyz |
					xyz := aCirclecPointi times: (cRadius at: j).
					xyz z: (cHeight at: j).
					ccPointi at: j put: xyz.
					ccWeighti at: j put: aCirclecWeighti * (aCurvecWeight at: j)]].
	answer _ccPoint: ccPoint.
	answer ccWeight: ccWeight.
	answer _cuKnot: aCircleNurbs cuKnot.
	answer _cvKnot: aCurveNurbs cuKnot.
	^answer</body>

<body package="CADSM-Geo" selector="fromSweep:">fromSweep: aSweep 
	| answer aCurveNurbs aCurvecPoint aCurvecWeight trajectoryNurbs trajectorycPoint trajectorycWeight m n ccPoint ccWeight |
	answer := self new.
	aCurveNurbs := aSweep aCurve rFpFNurbs.
	aCurvecPoint := aCurveNurbs cPoint.
	aCurvecWeight := aCurveNurbs cWeight.
	trajectoryNurbs := aSweep trajectory aNurbs.
	trajectorycPoint := trajectoryNurbs cPoint.
	trajectorycWeight := trajectoryNurbs cWeight.
	m := aCurvecPoint size.
	n := trajectorycPoint size.
	ccPoint := StMFullMatrix new: m by: n.
	ccWeight := StMFullMatrix new: m by: n.
	1 to: m
		do: 
			[:i | 
			| ccPointi ccWeighti aCurvecPointi aCurvecWeighti |
			ccPointi := ccPoint at: i.
			ccWeighti := ccWeight at: i.
			aCurvecPointi := aCurvecPoint at: i.
			aCurvecWeighti := aCurvecWeight at: i.
			1 to: n
				do: 
					[:j | 
					| trajectorycPointj trajectorycWeightj xyz |
					trajectorycPointj := trajectorycPoint at: j.
					trajectorycWeightj := trajectorycWeight at: j.
					xyz := aCurvecPointi plusFullColumn: trajectorycPointj.
					ccPointi at: j put: xyz.
					ccWeighti at: j put: aCurvecWeighti * trajectorycWeightj]].
	answer _ccPoint: ccPoint.
	answer ccWeight: ccWeight.
	answer _cuKnot: aCurveNurbs cuKnot.
	answer _cvKnot: trajectoryNurbs cuKnot.
	answer privateCalcBoundingBox.
	^answer</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsSurface class</class-id> <category>examples</category>

<body package="CADSM-Geo" selector="example1">example1
	"NurbsSurface example1"

	| answer |
	answer := self exampleCylinder.
	answer atu: -1.0d v: 0.0d.
	answer atu: -0.5d v: 0.0d.
	answer atu: 0.0d v: 0.0d.
	answer atu: 0.5d v: 0.0d.
	answer atu: 1.0d v: 0.0d.
	answer atu: 1.5d v: 0.0d.
	answer atu: 2.0d v: 0.0d.
	answer atu: 2.5d v: 0.0d.
	answer atu: 3.0d v: 0.0d.
	answer atu: 3.5d v: 0.0d.
	answer atu: 4.0d v: 0.0d.
	answer atu: 4.5d v: 0.0d.
	answer atu: 5.0d v: 0.0d</body>

<body package="CADSM-Geo" selector="example2">example2
	"NurbsSurface example2"

	| answer |
	answer := self exampleCylinder.
	answer 
		partialu: 1
		partialv: 1
		u: -1.0d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: -0.5d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 0.0d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 0.5d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 1.0d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 1.5d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 2.0d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 2.5d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 3.0d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 3.5d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 4.0d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 4.5d
		v: 0.0d.
	answer 
		partialu: 1
		partialv: 1
		u: 5.0d
		v: 0.0d</body>

<body package="CADSM-Geo" selector="exampleCylinder">exampleCylinder
	"NurbsSurface exampleCylinder"

	| ccPoint ccWeight cuKnot cvKnot |
	ccPoint := StMFullMatrix new: 9 by: 2.
	ccPoint at: 1 and: 1 put: (0 , -1 , 0) asFullColumn.
	ccPoint at: 2 and: 1 put: (1 , -1 , 0) asFullColumn.
	ccPoint at: 3 and: 1 put: (1 , 0 , 0) asFullColumn.
	ccPoint at: 4 and: 1 put: (1 , 1 , 0) asFullColumn.
	ccPoint at: 5 and: 1 put: (0 , 1 , 0) asFullColumn.
	ccPoint at: 6 and: 1 put: (-1 , 1 , 0) asFullColumn.
	ccPoint at: 7 and: 1 put: (-1 , 0 , 0) asFullColumn.
	ccPoint at: 8 and: 1 put: (-1 , -1 , 0) asFullColumn.
	ccPoint at: 9 and: 1 put: (0 , -1 , 0) asFullColumn.
	ccPoint at: 1 and: 2 put: (0 , -1 , 1) asFullColumn.
	ccPoint at: 2 and: 2 put: (1 , -1 , 1) asFullColumn.
	ccPoint at: 3 and: 2 put: (1 , 0 , 1) asFullColumn.
	ccPoint at: 4 and: 2 put: (1 , 1 , 1) asFullColumn.
	ccPoint at: 5 and: 2 put: (0 , 1 , 1) asFullColumn.
	ccPoint at: 6 and: 2 put: (-1 , 1 , 1) asFullColumn.
	ccPoint at: 7 and: 2 put: (-1 , 0 , 1) asFullColumn.
	ccPoint at: 8 and: 2 put: (-1 , -1 , 1) asFullColumn.
	ccPoint at: 9 and: 2 put: (0 , -1 , 1) asFullColumn.
	ccWeight := StMFullMatrix new: 9 by: 2.
	ccWeight at: 1 and: 1 put: 1.0d.
	ccWeight at: 2 and: 1 put: 1 / 2.0d sqrt.
	ccWeight at: 3 and: 1 put: 1.0d.
	ccWeight at: 4 and: 1 put: 1 / 2.0d sqrt.
	ccWeight at: 5 and: 1 put: 1.0d.
	ccWeight at: 6 and: 1 put: 1 / 2.0d sqrt.
	ccWeight at: 7 and: 1 put: 1.0d.
	ccWeight at: 8 and: 1 put: 1 / 2.0d sqrt.
	ccWeight at: 9 and: 1 put: 1.0d.
	ccWeight at: 1 and: 2 put: 1.0d.
	ccWeight at: 2 and: 2 put: 1 / 2.0d sqrt.
	ccWeight at: 3 and: 2 put: 1.0d.
	ccWeight at: 4 and: 2 put: 1 / 2.0d sqrt.
	ccWeight at: 5 and: 2 put: 1.0d.
	ccWeight at: 6 and: 2 put: 1 / 2.0d sqrt.
	ccWeight at: 7 and: 2 put: 1.0d.
	ccWeight at: 8 and: 2 put: 1 / 2.0d sqrt.
	ccWeight at: 9 and: 2 put: 1.0d.
	cuKnot := #(0 0 0 1 1 2 2 3 3 4 4 4).
	cvKnot := #(0 0 1 1).
	^(self new) _ccPoint: ccPoint; ccWeight: ccWeight; _cuKnot: cuKnot; _cvKnot: cvKnot; yourself</body>

<body package="CADSM-Geo" selector="exampleSphere">exampleSphere
	"NurbsSurface exampleSphere"

	| aSphere aNurbs |
	aSphere := CADSM.Geo.CADSMGeoSphericalSurface new radius: 1.0d.
	aNurbs := CADSMGeoNurbsSurface fromSolidOfRevolution: aSphere.
	(aNurbs asJunOpenGL3dNurbsSurface)
		paint: ColorValue blue;
		show</body>

<body package="CADSM-Geo" selector="exampleTorus">exampleTorus
	"NurbsSurface exampleTorus"

	| aTorus aNurbs |
	aTorus := (CADSM.Geo.CADSMGeoToroidalSurface new)
				majorRadius: 1.0d;
				minorRadius: 1.0d;
				yourself.
	aNurbs := CADSMGeoNurbsSurface fromSolidOfRevolution: aTorus.
	(aNurbs asJunOpenGL3dNurbsSurface)
		paint: ColorValue blue;
		show</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerspectiveCamera</class-id> <category>projection</category>

<body package="CADSM-Geo" selector="pickAt:aContext:">pickAt: rvGLpvGL aContext: aContext 
	aContext pickAt: rvGLpvGL aPerspectiveCamera: self</body>

<body package="CADSM-Geo" selector="projectOn:">projectOn: aRenderingContext 
	super projectOn: aRenderingContext.
	aRenderingContext perspective: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerspectiveCamera</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	| aAFf rFfF |
	super initialize.
	distance := self defaultDistance.
	height := distance / self ratio.
	viewFactor := self defaultViewFactor.
	near := distance / viewFactor.
	far := distance * viewFactor.
	aAFf := StMFullMatrix rotationMatrixFromzDir: (StMFullColumn 
						with: -1.0d
						with: -1.0d
						with: 1.0d)
				xDir: (StMFullColumn 
						with: 1.0d
						with: -1.0d
						with: 0.0d).
	rFfF := aAFf timesFullColumn: (StMFullColumn 
						with: 0.0d
						with: 0.0d
						with: distance).
	aRefFrame rFfF: rFfF aAFf: aAFf.
	shading := self defaultShading.
	presentation := self defaultPresentation.
	lineSmoothBoolean := false.
	polygonSmoothBoolean := false.
	cLighting := CADSM.Misc.CADSMMiscOrderedSet new.
	self privateCalcBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerspectiveCamera</class-id> <category>menubar items</category>

<body package="CADSM-Geo" selector="menuViewYupQuadmpm">menuViewYupQuadmpm
	| rFfocusF reyefocus ufocuseyeF rFeyeF uFupF |
	rFfocusF := aRefFrame rFpFfromrfpf: (StCAD.StMath.StMFullColumn 
						with: 0.0d
						with: 0.0d
						with: distance negated).
	reyefocus := distance.
	ufocuseyeF := (StCAD.StMath.StMFullColumn 
				with: -1.0d
				with: 1.0d
				with: -1.0d) normalizeSelf.
	rFeyeF := rFfocusF plusFullColumn: ufocuseyeF times: reyefocus.
	uFupF := StCAD.StMath.StMFullColumn 
				with: 0.0d
				with: 1.0d
				with: 0.0d.
	aRefFrame rFfF: rFeyeF
		aAFf: (StMFullMatrix rotationMatrixFromzDir: ufocuseyeF yDir: uFupF)</body>

<body package="CADSM-Geo" selector="menuViewYupXright">menuViewYupXright
	| rFfocusF reyefocus ufocuseyeF rFeyeF uFupF |
	rFfocusF := aRefFrame rFpFfromrfpf: (StCAD.StMath.StMFullColumn 
						with: 0.0d
						with: 0.0d
						with: distance negated).
	reyefocus := distance.
	ufocuseyeF := StCAD.StMath.StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: 1.0d.
	rFeyeF := rFfocusF plusFullColumn: ufocuseyeF times: reyefocus.
	uFupF := StCAD.StMath.StMFullColumn 
				with: 0.0d
				with: 1.0d
				with: 0.0d.
	aRefFrame rFfF: rFeyeF
		aAFf: (StMFullMatrix rotationMatrixFromzDir: ufocuseyeF yDir: uFupF)</body>

<body package="CADSM-Geo" selector="menuViewZupQuadmmp">menuViewZupQuadmmp
	| rFfocusF reyefocus ufocuseyeF rFeyeF uFupF |
	rFfocusF := aRefFrame rFpFfromrfpf: (StCAD.StMath.StMFullColumn 
						with: 0.0d
						with: 0.0d
						with: distance negated).
	reyefocus := distance.
	ufocuseyeF := (StCAD.StMath.StMFullColumn 
				with: -1.0d
				with: -1.0d
				with: 1.0d) normalizeSelf.
	rFeyeF := rFfocusF plusFullColumn: ufocuseyeF times: reyefocus.
	uFupF := StCAD.StMath.StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: 1.0d.
	aRefFrame rFfF: rFeyeF
		aAFf: (StMFullMatrix rotationMatrixFromzDir: ufocuseyeF yDir: uFupF)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerspectiveCamera</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="calc">calc
	near := distance / viewFactor.
	far := distance * viewFactor</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSMMiscBoundingBox origin: (StMFullColumn zero: 3)
				corner: (StMFullColumn zero: 3).
	self privateCalcBoundingBox: self cItemWithBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerspectiveCamera</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aRenderingContextOn:">aRenderingContextOn: aRetainedMedium 
	| dict aRenderingContext |
	dict := IdentityDictionary new: 5.
	dict at: #solid put: OpenGLSolidRenderingContext.
	dict at: #hiddenline put: OpenGLHiddenLineRenderingContext.
	dict at: #wireframe put: OpenGLWireframeRenderingContext.
	aRenderingContext := (dict at: presentation) on: aRetainedMedium.
	aRenderingContext clear.
	aRenderingContext obeyPerspectiveCamera: self.
	^aRenderingContext</body>

<body package="CADSM-Geo" selector="distance:">distance: anObject 
	distance := anObject.
	self calc</body>

<body package="CADSM-Geo" selector="fovy">fovy
	^JunAngle fromRad: (height / 2 / distance) arcTan * 2</body>

<body package="CADSM-Geo" selector="height">height
	^height</body>

<body package="CADSM-Geo" selector="height:">height: anObject 
	height := anObject</body>

<body package="CADSM-Geo" selector="sightPoint">sightPoint
	^aRefFrame rOpOfromrfpf: (StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: distance negated)</body>

<body package="CADSM-Geo" selector="viewFactor">viewFactor
	^viewFactor</body>

<body package="CADSM-Geo" selector="viewFactor:">viewFactor: anObject 
	viewFactor := anObject.
	self calc</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPerspectiveCamera</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isPerspective">isPerspective
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCylindricalJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDCylindricalJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'CylindricalJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRectSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aSup:">aSup: aSpatialItem 
	aSup := aSpatialItem</body>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsSurface fromRectSurface: self</body>

<body package="CADSM-Geo" selector="maxxmaxymaxz">maxxmaxymaxz
	^aBoundingBox maxxmaxymaxz</body>

<body package="CADSM-Geo" selector="maxxmaxyminz">maxxmaxyminz
	^aBoundingBox maxxmaxyminz</body>

<body package="CADSM-Geo" selector="maxxminymaxz">maxxminymaxz
	^aBoundingBox maxxminymaxz</body>

<body package="CADSM-Geo" selector="maxxminyminz">maxxminyminz
	^aBoundingBox maxxminyminz</body>

<body package="CADSM-Geo" selector="minxmaxymaxz">minxmaxymaxz
	^aBoundingBox minxmaxymaxz</body>

<body package="CADSM-Geo" selector="minxmaxyminz">minxmaxyminz
	^aBoundingBox minxmaxyminz</body>

<body package="CADSM-Geo" selector="minxminymaxz">minxminymaxz
	^aBoundingBox minxminymaxz</body>

<body package="CADSM-Geo" selector="minxminyminz">minxminyminz
	^aBoundingBox minxminyminz</body>

<body package="CADSM-Geo" selector="reverseNew">reverseNew
	"
	For plane loops only. 
	Flip refFrame 180 degrees about x-axis. 
	Reverse order of rfpointsf. 
	Negate all y coordinates of rfpointsf. 
	"

	| answer |
	answer := self copy.
	answer aRefFrame rotatex: Double pi.
	answer aBoundingBox reverseSelf.
	^answer</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	"
	For plane loops only. 
	Flip refFrame 180 degrees about x-axis. 
	Reverse order of rfpointsf. 
	Negate all y coordinates of rfpointsf. 
	"

	aRefFrame rotatex: Double pi.
	aBoundingBox reverseSelf.
	^self</body>

<body package="CADSM-Geo" selector="rSkFacePointSkAt:">rSkFacePointSkAt: uv 
	^aRefFrame rFpFfromrfpf: (self value: uv)</body>

<body package="CADSM-Geo" selector="value:">value: uv 
	^uv</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRectSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="cEndSingularityOf:">cEndSingularityOf: aaCurve 
	^StMArray with: false with: false</body>

<body package="CADSM-Geo" selector="conditionSelf">conditionSelf
	| tol minCorner maxCorner |
	tol := 1.0d-3 * aBoundingBox diagonal_length.
	minCorner := aBoundingBox minCorner.
	minCorner x: minCorner x - tol.
	minCorner y: minCorner y - tol.
	maxCorner := aBoundingBox maxCorner.
	maxCorner x: maxCorner x + tol.
	maxCorner y: maxCorner y + tol</body>

<body package="CADSM-Geo" selector="condition_cuv:">condition_cuv: aCurve 
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="condition_cuv:within:">condition_cuv: aaCurve within: aaBoundingRectangle 
	^self uvBound</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^CADSMGeoNurbsSurface fromRectSurface: self</body>

<body package="CADSM-Geo" selector="smooth_cuv:">smooth_cuv: aCurve 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="smooth_cuv:within:">smooth_cuv: aCurve within: uvBound 
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:">uvCurveOfEllipticArc: aEllipticArc 
	"
	aAFR*aARe := aAFe
	aARe := aAFRT*aAFe
	"

	| uvEllipticArc aAFf tol |
	uvEllipticArc := aEllipticArc copy.
	uvEllipticArc isSpatial: false.
	aAFf := aRefFrame aAFf 
				transposeTimesFullMatrix: aEllipticArc aRefFrame aAFf.
	tol := 1.0d-9.
	self assert: [(aAFf column: 3) length &gt; (1.0d - tol)].
	(uvEllipticArc aRefFrame)
		rFfF: (self uvwOfPoint: aEllipticArc aRefFrame rFfF);
		aAFf: aAFf.
	uvEllipticArc
		scaleF: self uvwScale;
		privateCalcBoundingBox.
	^uvEllipticArc</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:preCurve:">uvCurveOfEllipticArc: aEllipticArc preCurve: preCurve 
	"
	aAFR*aARe := aAFe
	aARe := aAFRT*aAFe
	"

	| uvEllipticArc aAFf tol |
	uvEllipticArc := aEllipticArc copy.
	uvEllipticArc isSpatial: false.
	aAFf := aRefFrame aAFf 
				transposeTimesFullMatrix: aEllipticArc aRefFrame aAFf.
	tol := 1.0d-9.
	self assert: [(aAFf column: 3) length &gt; (1.0d - tol)].
	(uvEllipticArc aRefFrame)
		rFfF: (self uvwOfPoint: aEllipticArc aRefFrame rFfF);
		aAFf: aAFf.
	uvEllipticArc
		scaleF: self uvwScale;
		privateCalcBoundingBox.
	^uvEllipticArc</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:">uvCurveOfLine: aLine 
	| uvstart uvend |
	uvstart := self uvOfPoint: aLine rfstartf.
	uvend := self uvOfPoint: aLine rfendf.
	^(CADSMGeoLine new)
		isSpatial: false;
		uvStart: uvstart;
		uvEnd: uvend;
		dsdt: 1 / (uvend - uvstart) length;
		privateCalcBoundingBox;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:preCurve:">uvCurveOfLine: aLine preCurve: preCurve 
	| uvstart uvend uvLine |
	uvstart := self uvOfPoint: aLine rfstartf.
	uvend := self uvOfPoint: aLine rfendf.
	uvLine := CADSMGeoLine new.
	uvLine
		isSpatial: false;
		uvStart: uvstart;
		uvEnd: uvend;
		dsdt: 1 / (uvend - uvstart) length;
		privateCalcBoundingBox.
	^uvLine</body>

<body package="CADSM-Geo" selector="uvCurveOfNurbsCurve:">uvCurveOfNurbsCurve: aNurbsCurve 
	"
	rFpF = rFpF
	rFRF + aAFR*rRpR = rFNF + aAFN*rNpN
	rRpR = aAFRT(rFNF - rFRF + aAFN*rNpN)
	"

	| aNurbsRefFrame aAFRT aAFN rFNFrFRF cuvPoint uvNurbsCurve |
	aNurbsRefFrame := aNurbsCurve aRefFrame.
	aAFRT := aRefFrame aAFf transpose.
	aAFN := aNurbsRefFrame aAFf.
	rFNFrFRF := aNurbsRefFrame rFfF minusFullColumn: aRefFrame rFfF.
	cuvPoint := aNurbsCurve cPoint collect: 
					[:rNpN | 
					| rRpR |
					rRpR := aAFRT 
								timesFullColumn: (rFNFrFRF plusFullColumn: (aAFN timesFullColumn: rNpN)).
					aBoundingBox uvwOfPoint: rRpR].
	uvNurbsCurve := aNurbsCurve copy.
	uvNurbsCurve aRefFrame fixedAtRef.
	uvNurbsCurve
		isSpatial: false;
		_cPoint: cuvPoint;
		be2D;
		privateCalcBoundingBox.
	^uvNurbsCurve</body>

<body package="CADSM-Geo" selector="uvCurveOfNurbsCurve:preCurve:">uvCurveOfNurbsCurve: aNurbsCurve preCurve: preCurve 
	"
	rFpF = rFpF
	rFRF + aAFR*rRpR = rFNF + aAFN*rNpN
	rRpR = aAFRT(rFNF - rFRF + aAFN*rNpN)
	"

	| aNurbsRefFrame aAFRT aAFN rFNFrFRF cuvPoint uvNurbsCurve |
	aNurbsRefFrame := aNurbsCurve aRefFrame.
	aAFRT := aRefFrame aAFf transpose.
	aAFN := aNurbsRefFrame aAFf.
	rFNFrFRF := aNurbsRefFrame rFfF minusFullColumn: aRefFrame rFfF.
	cuvPoint := aNurbsCurve cPoint collect: 
					[:rNpN | 
					| rRpR |
					rRpR := aAFRT 
								timesFullColumn: (rFNFrFRF plusFullColumn: (aAFN timesFullColumn: rNpN)).
					aBoundingBox uvwOfPoint: rRpR].
	uvNurbsCurve := aNurbsCurve copy.
	uvNurbsCurve aRefFrame fixedAtRef.
	uvNurbsCurve
		isSpatial: false;
		_cPoint: cuvPoint;
		be2D;
		privateCalcBoundingBox.
	^uvNurbsCurve</body>

<body package="CADSM-Geo" selector="uvOfPoint:">uvOfPoint: rFpF 
	| uvw |
	uvw := self uvwOfPoint: rFpF.
	^uvw copyFrom: 1 to: 2</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound:">uvShiftToFituvBound: uvBound 
	^(self uvBoundTol contains: uvBound) 
		ifTrue: [nil]
		ifFalse: 
			[self assert: [false].
			nil]</body>

<body package="CADSM-Geo" selector="uvwOfPoint:">uvwOfPoint: rFpF 
	| rfpf |
	rfpf := aRefFrame rfpffromrFpF: rFpF.
	^aBoundingBox uvwOfPoint: rfpf</body>

<body package="CADSM-Geo" selector="uvwScale">uvwScale
	^aBoundingBox uvwScale</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRectSurface</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="printVerboseOn:">printVerboseOn: aStream 
	aStream
		nextPutAll: 'RectSurface';
		cr;
		printVerbose: aRefFrame;
		cr;
		printVerbose: aBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMarker</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="findMarkerNamed:">findMarkerNamed: nameComponents 
	self name = (nameComponents at: 1) ifFalse: [^nil].
	^self</body>

<body package="CADSM-Geo" selector="findMarkerNamedOld:">findMarkerNamedOld: nameComponents 
	self name = (nameComponents at: 1) ifFalse: [^nil].
	^self</body>

<body package="CADSM-Geo" selector="rpmp">rpmp
	| anyPart rPmP rPpP aAPp |
	anyPart := self anyPart.
	rPmP := aRefFrame aSup rFfF.
	rPpP := anyPart rPcmP.
	aAPp := anyPart aAPcm.
	^aAPp transposeTimesFullColumn: (rPmP minusFullColumn: rPpP)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMarker</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	self privateCalcBoundingBox</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMarker</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSMMiscBoundingBox origin: (StMFullColumn zero: 3)
				corner: (StMFullColumn zero: 3)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMarker</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	"Do nothing."

	</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMassMarker</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aJppx">aJppx
	^aJppx</body>

<body package="CADSM-Geo" selector="aJppx:">aJppx: anObject
	aJppx := anObject</body>

<body package="CADSM-Geo" selector="aJppy">aJppy
	^aJppy</body>

<body package="CADSM-Geo" selector="aJppy:">aJppy: anObject
	aJppy := anObject</body>

<body package="CADSM-Geo" selector="aJppz">aJppz
	^aJppz</body>

<body package="CADSM-Geo" selector="aJppz:">aJppz: anObject
	aJppz := anObject</body>

<body package="CADSM-Geo" selector="density">density
	^density</body>

<body package="CADSM-Geo" selector="density:">density: anObject
	density := anObject</body>

<body package="CADSM-Geo" selector="mass">mass
	^mass</body>

<body package="CADSM-Geo" selector="mass:">mass: anObject
	mass := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMassMarker</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="zeroSelf">zeroSelf
	mass := 0.0d.
	aJppx := 0.0d.
	aJppy := 0.0d.
	aJppz := 0.0d.
	density := 0.0d</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoMassMarker</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="mJpp">mJpp
	^StMDiagonalMatrix
		with: self aJppx
		with: self aJppy
		with: self aJppz</body>

<body package="CADSM-Geo" selector="qEp">qEp
	^aRefFrame aAOf mbdEulerParameters</body>

<body package="CADSM-Geo" selector="rOcmO">rOcmO
	^aRefFrame rOfO</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCurveMarker</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="s">s
	^s</body>

<body package="CADSM-Geo" selector="s:">s: col 
	s := col</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	self aInputData: self dataFromCurrentState</body>

<body package="CADSM-Geo" selector="trigs:">trigs: double 
	| rFfFEqn aAFf1 aAFf2 aAFf3 aAFf rFfF |
	s := double.
	rFfFEqn := aSup rfCurvef.
	rFfF := rFfFEqn y: s.
	aAFf1 := (rFfFEqn dydx: s) normalizeSelf.
	aAFf2 := StMFullColumn 
				with: 0.0d
				with: 0.0d
				with: 1.0d.
	aAFf3 := aAFf1 cross: aAFf2.
	aAFf := StMFullMatrix new: 3 by: 3.
	aAFf 
		at: 1
		and: 1
		putFullColumn: aAFf1.
	aAFf 
		at: 1
		and: 2
		putFullColumn: aAFf2.
	aAFf 
		at: 1
		and: 3
		putFullColumn: aAFf3.
	aRefFrame quietlyrFfF: rFfF aAFf: aAFf</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCurveMarker</class-id> <category>displaying</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^[(self dataSeries at: integer) notNil] 
		on: Object subscriptOutOfBoundsSignal
		do: [:ex | ex return: false]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCurveMarker</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| aMbDEndFrame |
	self dataSeries: OrderedCollection new.
	self discontinuities: OrderedCollection new.
	aMbDEndFrame := CADSMMbDEndFrameqcs new.
	aMbDEndFrame
		name: self name;
		s: (StMFullColumn with: 0.0d);
		svel: (StMFullColumn with: 0.0d).
	aSup mbdObject addEndFrame: aMbDEndFrame.
	self mbdObject: aMbDEndFrame</body>

<body package="CADSM-Geo" selector="dataFromCurrentState">dataFromCurrentState
	^(CADSMDataSSdotSddot new)
		s: s;
		sdot: (StMArray zero: 1);
		sddot: (StMArray zero: 1);
		yourself</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	| data |
	data := self dataSeries at: integer.
	self trigs: (data s at: 1)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAmbientLighting</class-id> <category>lighting</category>

<body package="CADSM-Geo" selector="lightingOn:">lightingOn: aRenderingContext 
	aRenderingContext lightAmbientColor: self color alpha: self alpha.
	aRenderingContext enableLighting</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoAmbientLighting</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aDialog">aDialog
	^StCAD.CADAmbientLightingDialog openOn: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurfaceMarker</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="dataFromCurrentState">dataFromCurrentState
	^(CADSMDataSSdotSddot new)
		s: s;
		sdot: (StMArray zero: 2);
		sddot: (StMArray zero: 2);
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoUniversalJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDUniversalJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'UniversalJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCurve</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aEdgeUseFrom:to:">aEdgeUseFrom: rfstartf to: rfendf 
	| aEdgeUse aVertexUse aLine |
	self halt: 'Edge should only be created by Model.'.
	aEdgeUse := CADSM.NMT.CADSMNMTEdge new newUse.
	aVertexUse := (CADSM.NMT.CADSMNMTVertex new: rfstartf) newUse.
	aEdgeUse aVertexUse: aVertexUse.
	aLine := self aLineFrom: rfstartf to: rfendf.
	aEdgeUse uvOFt: aLine.
	aEdgeUse isSameSense: true.
	aVertexUse t: 0.0d.
	^aEdgeUse</body>

<body package="CADSM-Geo" selector="aLineFrom:to:">aLineFrom: rfstartf to: rfendf 
	| aLine |
	aLine := CADSMGeoLine new.
	aLine aSup: aSup.
	aLine aRefFrame: aRefFrame copy.
	aLine rfstartf: rfstartf.
	aLine rfendf: rfendf.
	aLine calc.
	aLine privateCalcBoundingBox.
	^aLine</body>

<body package="CADSM-Geo" selector="asPolyline">asPolyline
	| polyline |
	polyline := CADSMGeoPolyline new.
	polyline aSup: aSup.
	polyline aRefFrame: aRefFrame copy.
	polyline rfpointsf: self rfpointsf.
	^polyline</body>

<body package="CADSM-Geo" selector="cEdgeUse">cEdgeUse
	| crfpointf n cEdgeUse |
	crfpointf := self crfpointf.
	n := crfpointf size - 1.
	cEdgeUse := OrderedCollection new: n.
	1 to: n
		do: 
			[:i | 
			cEdgeUse 
				add: (self aEdgeUseFrom: (crfpointf at: i) to: (crfpointf at: i + 1))].
	^cEdgeUse</body>

<body package="CADSM-Geo" selector="cEdgeUse1">cEdgeUse1
	| crSkpointSk n cEdgeUse |
	crSkpointSk := self crSkpointSk.
	n := crSkpointSk size - 1.
	cEdgeUse := OrderedCollection new: n.
	1 to: n
		do: 
			[:i | 
			cEdgeUse 
				add: (self aEdgeUseFrom: (crSkpointSk at: i) to: (crSkpointSk at: i + 1))].
	^cEdgeUse</body>

<body package="CADSM-Geo" selector="create_glCurve">create_glCurve
	^self create_glNurbs</body>

<body package="CADSM-Geo" selector="create_glTrimCurve">create_glTrimCurve
	^self create_glNurbs</body>

<body package="CADSM-Geo" selector="crSkpointSk">crSkpointSk
	^self crfpointf collect: [:rfpointf | aRefFrame rFpFfromrfpf: rfpointf]</body>

<body package="CADSM-Geo" selector="cuv">cuv
	^self triggerEvent: #cuv</body>

<body package="CADSM-Geo" selector="cuv:">cuv: cuv 
	self removeActionsForEvent: #cuv.
	cuv ifNotNil: 
			[self 
				when: #cuv
				ask: cuv
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="glCurve">glCurve
	^(self triggerEvent: #glCurve) ifNil: 
			[| answer |
			answer := self create_glCurve.
			self glCurve: answer.
			answer]</body>

<body package="CADSM-Geo" selector="glCurve:">glCurve: glCurve 
	self removeActionsForEvent: #glCurve.
	glCurve ifNotNil: 
			[self 
				when: #glCurve
				ask: glCurve
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="glTrimCurve">glTrimCurve
	^(self triggerEvent: #glTrimCurve) ifNil: 
			[| answer |
			answer := self create_glTrimCurve.
			self glTrimCurve: answer.
			answer]</body>

<body package="CADSM-Geo" selector="glTrimCurve:">glTrimCurve: glTrimCurve 
	self removeActionsForEvent: #glTrimCurve.
	glTrimCurve ifNotNil: 
			[self 
				when: #glTrimCurve
				ask: glTrimCurve
				perform: #yourself]</body>

<body package="CADSM-Geo" selector="rFpFNurbs">rFpFNurbs
	| aNurbs |
	aNurbs := self aNurbs copy.
	aNurbs transformSelfBy_rFfF: aRefFrame rFfF aAFf: aRefFrame aAFf.
	^aNurbs</body>

<body package="CADSM-Geo" selector="rFpF_u:">rFpF_u: u 
	^aRefFrame rFpFfromrfpf: (self rfpf_u: u)</body>

<body package="CADSM-Geo" selector="rfpf_u:">rfpf_u: u 
	self subclassResponsibility</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCurve</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="uv_connectTo:">uv_connectTo: aCurve 
	self cuv ifNotNil: 
			[:cuv | 
			| uvlast uvfirst |
			uvlast := cuv last.
			uvfirst := aCurve cuv first.
			uvfirst u: uvlast u.
			uvfirst v: uvlast v]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCurve</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	self glCurve: nil.
	self aNurbs: nil</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="calc">calc
	dsdu := rfendf minusFullColumn: rfstartf</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := isSpatial 
				ifTrue: [CADSM.Misc.CADSMMiscBoundingBox new]
				ifFalse: [CADSM.Misc.CADSMMiscBoundingRectangle new].
	aBoundingBox expandToBound: rfstartf.
	aBoundingBox expandToBound: rfendf</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="atU:">atU: u 
	^rfstartf plusFullColumn: dsdu times: u</body>

<body package="CADSM-Geo" selector="c2Point">c2Point
	| aPoint bPoint |
	aPoint := aRefFrame rFpFfromrfpf: rfstartf.
	bPoint := aRefFrame rFpFfromrfpf: rfendf.
	^StMFullColumn with: aPoint with: bPoint</body>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsCurve fromLine: self</body>

<body package="CADSM-Geo" selector="rfendf">rfendf
	^rfendf</body>

<body package="CADSM-Geo" selector="rfendf:">rfendf: anObject
	rfendf := anObject</body>

<body package="CADSM-Geo" selector="rfstartf">rfstartf
	^rfstartf</body>

<body package="CADSM-Geo" selector="rfstartf:">rfstartf: anObject
	rfstartf := anObject</body>

<body package="CADSM-Geo" selector="uvEnd">uvEnd
	self assert: [isSpatial not].
	^rfendf copy</body>

<body package="CADSM-Geo" selector="uvStart">uvStart
	self assert: [isSpatial not].
	^rfstartf copy</body>

<body package="CADSM-Geo" selector="value:">value: u 
	^rfstartf plusFullColumn: dsdu times: u</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="aDir">aDir
	^rfendf minusFullColumn: rfstartf</body>

<body package="CADSM-Geo" selector="boundConicalSurface:">boundConicalSurface: aConicalSurface 
	aConicalSurface boundByLine: self</body>

<body package="CADSM-Geo" selector="boundCylindricalSurface:">boundCylindricalSurface: aCylindricalSurface 
	aCylindricalSurface boundByLine: self</body>

<body package="CADSM-Geo" selector="boundNurbsSurface:">boundNurbsSurface: aNurbsSurface 
	aNurbsSurface boundByLine: self</body>

<body package="CADSM-Geo" selector="boundRectSurface:">boundRectSurface: aRectSurface 
	aRectSurface boundByLine: self</body>

<body package="CADSM-Geo" selector="boundSweep:">boundSweep: aSweep 
	aSweep boundByLine: self</body>

<body package="CADSM-Geo" selector="cPoint">cPoint
	^Array with: rfstartf with: rfendf</body>

<body package="CADSM-Geo" selector="dsdt:">dsdt: dsdt 
	dsdu := dsdt</body>

<body package="CADSM-Geo" selector="finalize_cuv">finalize_cuv
	self cuv ifNotNil: 
			[:cuv | 
			| uvStart uvEnd |
			uvStart := cuv first copy.
			uvEnd := cuv last copy.
			self
				isSpatial: false;
				uvStart: uvStart;
				uvEnd: uvEnd;
				dsdt: 1 / (uvEnd - uvStart) length;
				privateCalcBoundingBox]</body>

<body package="CADSM-Geo" selector="finalize_cuv1">finalize_cuv1
	self cuv ifNotNil: 
			[:cuv | 
			| uvStart uvEnd |
			uvStart := cuv first.
			uvEnd := cuv last.
			self
				isSpatial: false;
				uvStart: uvStart;
				uvEnd: uvEnd;
				dsdt: 1 / (uvEnd - uvStart) length;
				privateCalcBoundingBox]</body>

<body package="CADSM-Geo" selector="nPoint:">nPoint: n 
	| delta answer |
	delta := (rfendf - rfstartf) / (n - 1).
	answer := StMFullColumn new: n.
	1 to: n
		do: [:i | answer at: i put: rfstartf + (delta times: (i - 1) asDouble)].
	^answer</body>

<body package="CADSM-Geo" selector="reverse">reverse
	| answer |
	answer := self copy.
	answer rfstartf: rfendf.
	answer rfendf: rfstartf.
	^answer</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	| temp |
	temp := rfstartf.
	rfstartf := rfendf.
	rfendf := temp.
	dsdu ifNotNil: [dsdu := dsdu negated]</body>

<body package="CADSM-Geo" selector="rFendF">rFendF
	^rfendf</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^CADSMGeoNurbsCurve fromLine: self</body>

<body package="CADSM-Geo" selector="rFstartF">rFstartF
	^rfstartf</body>

<body package="CADSM-Geo" selector="uend">uend
	^isSpatial ifTrue: [self halt: 'Check this'] ifFalse: [rfendf u]</body>

<body package="CADSM-Geo" selector="uOfPoint:">uOfPoint: rFpF 
	| avec bvec |
	avec := rFpF - rfstartf.
	bvec := rfendf - rfstartf.
	self assert: 
			[| tol |
			tol := 1.0d-3.
			self toTranscriptShow: 'Line ((avec cross: bvec) length / tol) &lt;1p&gt;'
				ifOverOne: (avec cross: bvec) length / tol.
			true].
	^(avec dot: bvec) / bvec sumOfSquares</body>

<body package="CADSM-Geo" selector="uvBound">uvBound
	self assert: [isSpatial not].
	^aBoundingBox</body>

<body package="CADSM-Geo" selector="uvCurveOnSurface:">uvCurveOnSurface: aSurface 
	| aaCurve |
	aaCurve := aSurface uvCurveOfLine: self.
"	aSurface condition_cuv: aaCurve."
	^aaCurve</body>

<body package="CADSM-Geo" selector="uvCurveOnSurface:preCurve:">uvCurveOnSurface: aSurface preCurve: preCurve 
	^aSurface uvCurveOfLine: self preCurve: preCurve</body>

<body package="CADSM-Geo" selector="uvend">uvend
	^isSpatial ifTrue: [self halt: 'Check this'] ifFalse: [rfendf copy]</body>

<body package="CADSM-Geo" selector="uvEnd:">uvEnd: uvend 
	rfendf := uvend</body>

<body package="CADSM-Geo" selector="uvShift:">uvShift: uvShift 
	self cuv do: [:uv | uv equalSelfPlus: uvShift]</body>

<body package="CADSM-Geo" selector="uvStart:">uvStart: uvstart 
	rfstartf := uvstart</body>

<body package="CADSM-Geo" selector="vend">vend
	^isSpatial ifTrue: [self halt: 'Check this'] ifFalse: [rfendf v]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>comparing</category>

<body package="CADSM-Geo" selector="=">= aObject 
	^self == aObject or: 
			[self class == aObject class and: 
					[(rfstartf - aObject rfstartf) length &lt; 1.0d-9 
						and: [(rfendf - aObject rfendf) length &lt; 1.0d-9]]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	rfstartf magnifySelf: aDouble.
	rfendf magnifySelf: aDouble.
	dsdu := dsdu ifNotNil: [dsdu * aDouble]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="printOn:">printOn: aStream 
	aStream nextPut: $a.
	aStream print: self class.
	aStream nextPut: $(.
	aStream
		cr;
		print: rfstartf.
	aStream
		cr;
		print: rfendf.
	aStream nextPut: $)</body>

<body package="CADSM-Geo" selector="printVerboseOn:">printVerboseOn: aStream 
	aStream
		nextPutAll: 'Line';
		cr;
		print: rfstartf;
		cr;
		print: rfendf</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	rfstartf := rfstartf copy.
	rfendf := rfendf copy</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLine class</class-id> <category>utilities</category>

<body package="CADSM-Geo" selector="dataIntersectionPoint:aDir:bPoint:bDir:tolerance:">dataIntersectionPoint: p0 aDir: v bPoint: q0 bDir: w tolerance: tol 
	| array rfpf rfqf |
	array := self 
				dataMinDistPoint: p0
				aDir: v
				bPoint: q0
				bDir: w.
	array ifNotNil: 
			[rfpf := array at: 1.
			rfqf := array at: 2.
			array
				at: 1 put: (rfqf - rfpf) length &lt;= tol;
				at: 2 put: (rfqf + rfpf times: 0.5d)].
	^array</body>

<body package="CADSM-Geo" selector="dataMinDistPoint:aDir:bPoint:bDir:">dataMinDistPoint: p0 aDir: v bPoint: q0 bDir: w 
	"
	Find the minimum distance between two lines. 
	Line is P(t) = P0 + tv. 
	Line is Q(u) = Q0 + uw. 
	Minimize P(t) - Q(u). 
	Therefore 
	t = w*(P0 - Q0) v*w - v*(P0 - Q0) w*w / (v*v w*w - v*w v*w). 
	u = w*(P0 - Q0) v*v - v*(P0 - Q0) w*v / (v*v w*w - v*w v*w). 
	"

	| p0mq0 vdotv wdotw vdotw vdotp0mq0 wdotp0mq0 denominator t u px qx |
	p0mq0 := p0 - q0.
	vdotv := v sumOfSquares.
	wdotw := w sumOfSquares.
	vdotw := v dot: w.
	vdotp0mq0 := v dot: p0mq0.
	wdotp0mq0 := w dot: p0mq0.
	denominator := vdotv * wdotw - (vdotw * vdotw).
	^denominator &gt; 0.0d 
		ifTrue: 
			[t := (wdotp0mq0 * vdotw - (vdotp0mq0 * wdotw)) / denominator.
			u := (wdotp0mq0 * vdotv - (vdotp0mq0 * vdotw)) / denominator.
			px := p0 plus: v times: t.
			qx := q0 plus: w times: u.
			Array 
				with: px
				with: qx
				with: t
				with: u]
		ifFalse: 
			["Lines are parallel."

			self assert: [false]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipse</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="cEdgeUse">cEdgeUse
	| cEdgeUse aEdgeUse rfstartf aVertexUse |
	self halt: 'Edge should only be created by Model.'.
	cEdgeUse := OrderedCollection new.
	aEdgeUse := CADSM.NMT.CADSMNMTEdge new newUse.
	rfstartf := StMFullColumn 
				with: xRadius
				with: 0.0d
				with: 0.0d.
	aVertexUse := (CADSM.NMT.CADSMNMTVertex new: rfstartf) newUse.
	aVertexUse t: 0.0d.
	aEdgeUse aVertexUse: aVertexUse.
	aEdgeUse uvOFt: self.
	aEdgeUse isSameSense: true.
	cEdgeUse add: aEdgeUse.
	^cEdgeUse</body>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsCurve fromEllipse: self</body>

<body package="CADSM-Geo" selector="rfpointsf">rfpointsf
	| nseg rfpointsf angle xi yi dangle |
	nseg := 16.
	dangle := TwoPi / nseg.
	rfpointsf := StMArray new: nseg + 1.
	1 to: nseg
		do: 
			[:i | 
			angle := (i - 1) * dangle.
			xi := xRadius * angle cos.
			yi := yRadius * angle sin.
			rfpointsf at: i
				put: (StMFullColumn 
						with: xi
						with: yi
						with: 0.0d)].
	rfpointsf at: nseg + 1 put: (rfpointsf at: 1).
	^rfpointsf</body>

<body package="CADSM-Geo" selector="value:">value: u 
	^StMFullColumn 
		with: xRadius * u cos
		with: yRadius * u sin
		with: 0.0d</body>

<body package="CADSM-Geo" selector="xRadius">xRadius
	^xRadius</body>

<body package="CADSM-Geo" selector="xRadius:">xRadius: anObject
	xRadius := anObject</body>

<body package="CADSM-Geo" selector="yRadius">yRadius
	^yRadius</body>

<body package="CADSM-Geo" selector="yRadius:">yRadius: anObject
	yRadius := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipse</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox origin: (StMFullColumn 
						with: xRadius negated
						with: yRadius negated
						with: 0.0d)
				corner: (StMFullColumn 
						with: xRadius
						with: yRadius
						with: 0.0d)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipse</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	xRadius := xRadius * aDouble.
	yRadius := yRadius * aDouble</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipse</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="radiusAt:">radiusAt: theta 
	^(self xyAt: theta) length</body>

<body package="CADSM-Geo" selector="rfpf_u:">rfpf_u: u 
	| theta |
	theta := u * Double twoPi.
	^StMFullColumn 
		with: xRadius * theta cos
		with: yRadius * theta sin
		with: 0.0d</body>

<body package="CADSM-Geo" selector="uOfPoint:">uOfPoint: rFpF 
	| rfpf the u |
	rfpf := aRefFrame rfpffromrFpF: rFpF.
	the := Double arcTan0to2piY: rfpf y / yRadius overX: rfpf x / xRadius.
	u := the / Double twoPi \\ 1.0d.
	self assert: 
			[| tol radius |
			tol := 1.0d-6 * (xRadius + yRadius) / 2.0d.
			radius := self radiusAt: the.
			self toTranscriptShow: 'Ellipse (z / tol) &lt;1p&gt;' ifOverOne: rfpf z abs / tol.
			self toTranscriptShow: 'Ellipse (dr / tol) &lt;1p&gt;'
				ifOverOne: (rfpf length - radius) abs / tol.
			true].
	^u</body>

<body package="CADSM-Geo" selector="uvAt:">uvAt: theta 
	^aRefFrame rFpFfromrfpf2D: (StMFullColumn with: xRadius * theta cos
				with: yRadius * theta sin)</body>

<body package="CADSM-Geo" selector="xyAt:">xyAt: theta 
	^StMFullColumn with: xRadius * theta cos with: yRadius * theta sin</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipticArc</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsCurve fromEllipticArc: self</body>

<body package="CADSM-Geo" selector="rfpointsf">rfpointsf
	| nseg rfpointsf angle xi yi dangle |
	nseg := 16.
	dangle := TwoPi / nseg.
	rfpointsf := StMArray new: nseg + 1.
	1 to: nseg
		do: 
			[:i | 
			angle := (i - 1) * dangle.
			xi := xRadius * angle cos.
			yi := yRadius * angle sin.
			rfpointsf at: i
				put: (StMFullColumn 
						with: xi
						with: yi
						with: 0.0d)].
	rfpointsf at: nseg + 1 put: (rfpointsf at: 1).
	^rfpointsf</body>

<body package="CADSM-Geo" selector="theEnd">theEnd
	^theEnd</body>

<body package="CADSM-Geo" selector="theEnd:">theEnd: anObject
	theEnd := anObject</body>

<body package="CADSM-Geo" selector="theStart">theStart
	^theStart</body>

<body package="CADSM-Geo" selector="theStart:">theStart: anObject
	theStart := anObject</body>

<body package="CADSM-Geo" selector="uend">uend
	^isSpatial 
		ifTrue: [self halt: 'Check this']
		ifFalse: [(self rfpfAt: theEnd) u]</body>

<body package="CADSM-Geo" selector="uOfPoint:">uOfPoint: rFpF 
	| rfpf the u |
	rfpf := aRefFrame rfpffromrFpF: rFpF.
	the := Double arcTan0to2piY: rfpf y / yRadius overX: rfpf x / xRadius.
	u := (the - theStart) / theEnd - theStart.
	self assert: 
			[| tol radius |
			tol := 1.0d-6 * (xRadius + yRadius) / 2.0d.
			radius := self radiusAt: the.
			self toTranscriptShow: 'Ellipse (z / tol) &lt;1p&gt;' ifOverOne: rfpf z abs / tol.
			self toTranscriptShow: 'Ellipse (dr / tol) &lt;1p&gt;'
				ifOverOne: (rfpf length - radius) abs / tol.
			true].
	^u</body>

<body package="CADSM-Geo" selector="uvEnd">uvEnd
	self assert: [isSpatial not].
	^self uvAt: theEnd</body>

<body package="CADSM-Geo" selector="uvend">uvend
	^isSpatial ifTrue: [self halt: 'Check this'] ifFalse: [self rfpfAt: theEnd]</body>

<body package="CADSM-Geo" selector="uvStart">uvStart
	self assert: [isSpatial not].
	^self uvAt: theStart</body>

<body package="CADSM-Geo" selector="_radius">_radius
	self assert: [xRadius = yRadius].
	^xRadius</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipticArc</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="boundConicalSurface:">boundConicalSurface: aConicalSurface 
	aConicalSurface boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="boundCylindricalSurface:">boundCylindricalSurface: aCylindricalSurface 
	aCylindricalSurface boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="boundNurbsSurface:">boundNurbsSurface: aNurbsSurface 
	aNurbsSurface boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="boundRectSurface:">boundRectSurface: aRectSurface 
	aRectSurface boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="boundSphericalSurface:">boundSphericalSurface: aSphericalSurface 
	aSphericalSurface boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="boundSurfaceOfRevolution:">boundSurfaceOfRevolution: aSurfaceOfRevolution 
	aSurfaceOfRevolution boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="boundToroidalSurface:">boundToroidalSurface: aToroidalSurface 
	aToroidalSurface boundByEllipticArc: self</body>

<body package="CADSM-Geo" selector="cnPoint:">cnPoint: n 
	^(theStart to: theEnd by: (theEnd - theStart) / (n - 1)) 
		collect: [:the | aRefFrame rFpFfromrfpf: (self rfpfAt: the)]</body>

<body package="CADSM-Geo" selector="conditionSelf">conditionSelf
	theStart &gt;= 0.0d 
		ifFalse: 
			[self theStart: theStart + TwoPi.
			self theEnd: theEnd + TwoPi.
			self conditionSelf].
	theStart &lt; theEnd 
		ifFalse: 
			[self theEnd: theEnd + TwoPi.
			self conditionSelf]</body>

<body package="CADSM-Geo" selector="cPoint">cPoint
	| n dthe stream |
	n := 64.
	dthe := Double twoPi / n.
	stream := (Array new: n + 1) writeStream.
	stream nextPut: (self rfpfAt: theStart).
	(theStart / dthe) ceiling to: (theEnd / dthe) floor
		do: [:i | stream nextPut: (self rfpfAt: i * dthe)].
	stream nextPut: (self rfpfAt: theEnd).
	^stream contents</body>

<body package="CADSM-Geo" selector="finalize_cuv">finalize_cuv
	self cuv ifNotNil: [self assert: false]</body>

<body package="CADSM-Geo" selector="isOK">isOK
	^xRadius &gt;= 0.0d and: [yRadius &gt;= 0.0d and: [theEnd &gt;= theStart]]</body>

<body package="CADSM-Geo" selector="nPoint:">nPoint: n 
	| dthe answer |
	dthe := (theEnd - theStart) / (n - 1).
	answer := (1 to: n) collect: 
					[:i | 
					| the |
					the := theStart + ((i - 1) * dthe).
					self rFpFAt: the].
	answer changeClassToThatOf: StMFullColumn basicNew.
	^answer</body>

<body package="CADSM-Geo" selector="reverse">reverse
	| newEllipticArc |
	newEllipticArc := self copy.
	newEllipticArc aRefFrame rotatex: Double pi.
	newEllipticArc theStart: TwoPi - theEnd.
	newEllipticArc theEnd: TwoPi - theStart.
	newEllipticArc conditionSelf.
	self assert: [newEllipticArc isOK].
	^newEllipticArc</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	| newStart newEnd |
	aRefFrame rotatex: Double pi.
	newStart := Double twoPi - theEnd.
	newEnd := Double twoPi - theStart.
	theStart := newStart.
	theEnd := newEnd</body>

<body package="CADSM-Geo" selector="rFendF">rFendF
	^self rFpFAt: theEnd</body>

<body package="CADSM-Geo" selector="rFendminusF">rFendminusF
	| dthe the |
	dthe := 0.001d * (theEnd - theStart).
	the := theEnd - dthe.
	^self rFpFAt: the</body>

<body package="CADSM-Geo" selector="rFpFAt:">rFpFAt: theta 
	^aRefFrame rFpFfromrfpf: (self rfpfAt: theta)</body>

<body package="CADSM-Geo" selector="rfpfAt:">rfpfAt: theta 
	^StMFullColumn 
		with: xRadius * theta cos
		with: yRadius * theta sin
		with: 0.0d</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^CADSMGeoNurbsCurve fromEllipticArc: self</body>

<body package="CADSM-Geo" selector="rFstartF">rFstartF
	^self rFpFAt: theStart</body>

<body package="CADSM-Geo" selector="rFstartplusF">rFstartplusF
	| dthe the |
	dthe := 0.001d * (theEnd - theStart).
	the := theStart + dthe.
	^self rFpFAt: the</body>

<body package="CADSM-Geo" selector="scaleF:">scaleF: uvwScale 
	"
	Stretching an oblique ellipse in XY direction.
	Refer to ecllipse4.sxw
	"

	| bryantAngles theXx sT cT sTsT cTcT s2T rx ry rxrx ryry cU cV cUcU cVcV num den phiUu sP cP cUsPsT cVcPcT cUsPcT cVcPsT cUcPsT cVsPcT cUcPcT cVsPsT cUcVrx cUcVry ru rv block tol |
	bryantAngles := aRefFrame aAFf bryantAngles.
	theXx := bryantAngles at: 3.
	tol := 1.0d-9.
	(theXx abs &lt;= tol 
		or: [(Double pi - theXx) abs &lt;= tol or: [(Double twoPi - theXx) abs &lt;= tol]]) 
			ifTrue: 
				[xRadius := xRadius * (uvwScale at: 1).
				yRadius := yRadius * (uvwScale at: 2)]
			ifFalse: 
				[sT := theXx sin.
				cT := theXx cos.
				sTsT := sT * sT.
				cTcT := cT * cT.
				s2T := 2.0d * sT * cT.
				rx := xRadius.
				ry := yRadius.
				rxrx := rx * rx.
				ryry := ry * ry.
				cU := uvwScale at: 1.
				cV := uvwScale at: 2.
				cUcU := cU * cU.
				cVcV := cV * cV.
				num := (rxrx - ryry) * cU * cV * s2T.
				den := (rxrx * cUcU - (ryry * cVcV)) * cTcT 
							- ((rxrx * cVcV - (ryry * cUcU)) * sTsT).
				phiUu := (num isZero and: [den isZero]) 
							ifTrue: [0.0d]
							ifFalse: [0.5d * (Double arcTan0to2piY: num overX: den)].
				sP := phiUu sin.
				cP := phiUu cos.
				cUsPsT := cU * sP * sT.
				cVcPcT := cV * cP * cT.
				cUsPcT := cU * sP * cT.
				cVcPsT := cV * cP * sT.
				cUcPsT := cU * cP * sT.
				cVsPcT := cV * sP * cT.
				cUcPcT := cU * cP * cT.
				cVsPsT := cV * sP * sT.
				cUcVrx := cU * cV * rx.
				cUcVry := cU * cV * ry.
				ru := (((cUsPsT + cVcPcT) / cUcVrx) squared 
							+ ((cUsPcT - cVcPsT) / cUcVry) squared) reciprocal 
							sqrt.
				rv := (((cUcPsT - cVsPcT) / cUcVrx) squared 
							+ ((cUcPcT + cVsPsT) / cUcVry) squared) reciprocal 
							sqrt.
				block := 
						[:the | 
						| x y |
						x := rx * the cos.
						y := ry * the sin.
						num := ru * (x negated * (cUsPcT - cVcPsT) + (y * (cUsPsT + cVcPcT))).
						den := rv * (x * (cUcPcT + cVsPsT) - (y * (cUcPsT - cVsPcT))).
						(num isZero and: [den isZero]) 
							ifTrue: [0.0d]
							ifFalse: [Double arcTan0to2piY: num overX: den]].
				theStart := block value: theStart.
				theEnd := block value: theEnd.
				theStart &gt; theEnd ifTrue: [theEnd := theEnd + Double twoPi].
				xRadius := ru.
				yRadius := rv.
				aRefFrame 
					aAFf: (StCAD.StGeo.GEOEulerAnglesxyz 
							with: (bryantAngles at: 1)
							with: (bryantAngles at: 2)
							with: phiUu) aA].
	self assert: [self isOK]</body>

<body package="CADSM-Geo" selector="tangentAt:">tangentAt: theta 
	^StMFullColumn 
		with: xRadius * theta sin negated
		with: yRadius * theta cos
		with: 0.0d</body>

<body package="CADSM-Geo" selector="tangentFAt:">tangentFAt: theta 
	^aRefFrame aAFf timesFullColumn: (self tangentAt: theta)</body>

<body package="CADSM-Geo" selector="uvBound">uvBound
	self assert: [isSpatial not].
	^aBoundingBox</body>

<body package="CADSM-Geo" selector="uvCurveOnSurface:">uvCurveOnSurface: aSurface 
	| aaCurve |
	aaCurve := aSurface uvCurveOfEllipticArc: self.
"	aSurface condition_cuv: aaCurve."
	^aaCurve</body>

<body package="CADSM-Geo" selector="uvCurveOnSurface:preCurve:">uvCurveOnSurface: aSurface preCurve: preCurve 
	^aSurface uvCurveOfEllipticArc: self preCurve: preCurve</body>

<body package="CADSM-Geo" selector="_radius:">_radius: radius 
	xRadius := radius.
	yRadius := radius</body>

<body package="CADSM-Geo" selector="_rFendF:">_rFendF: rFpF 
	| rfpf x y r |
	rfpf := aRefFrame rfpffromrFpF: rFpF.
	x := rfpf x.
	y := rfpf y.
	theEnd := Double arcTan0to2piY: y / yRadius overX: x / xRadius.
	theEnd &lt; StMMachineAccuracy OfDoubleTimesFour ifTrue: [theEnd := TwoPi].
	r := (x * x + (y * y)) sqrt.
	self assert: 
			[| tol |
			tol := 1.0d-6 * (xRadius + yRadius) / 2.0d.
			self toTranscriptShow: 'EllipseArc (dr / tol) &lt;1p&gt;'
				ifOverOne: (r - (self radiusAt: theEnd)) abs / tol.
			true]</body>

<body package="CADSM-Geo" selector="_rFstartF:">_rFstartF: rFpF 
	| rfpf x y r |
	rfpf := aRefFrame rfpffromrFpF: rFpF.
	x := rfpf x.
	y := rfpf y.
	theStart := Double arcTan0to2piY: y / yRadius overX: x / xRadius.
	theStart &gt; (TwoPi - StMMachineAccuracy OfDoubleTimesFour) 
		ifTrue: [theStart := 0.0d].
	r := (x * x + (y * y)) sqrt.
	self assert: 
			[| tol |
			tol := 1.0d-6 * (xRadius + yRadius) / 2.0d.
			self toTranscriptShow: 'EllipseArc (dr / tol) &lt;1p&gt;'
				ifOverOne: (r - (self radiusAt: theStart)) abs / tol.
			true]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipticArc</class-id> <category>comparing</category>

<body package="CADSM-Geo" selector="=">= aObject 
	^self equal: aObject</body>

<body package="CADSM-Geo" selector="equal:">equal: aObject 
	| tol n c1nPoint c2nPoint |
	tol := 1.0d-9.
	n := 4.
	^self == aObject or: 
			[self class == aObject class and: 
					[(xRadius - aObject xRadius) abs &lt; tol and: 
							[(yRadius - aObject yRadius) abs &lt; tol and: 
									[c1nPoint := aObject cnPoint: n.
									c2nPoint := self cnPoint: n.
									(1 to: n) 
										allSatisfy: [:i | ((c1nPoint at: i) - (c2nPoint at: i)) length &lt; tol]]]]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipticArc</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	| block half_pi |
	isSpatial 
		ifTrue: 
			[aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox new.
			block := [:the | aBoundingBox expandToBound: (self rfpfAt: the)]]
		ifFalse: 
			[aBoundingBox := CADSM.Misc.CADSMMiscBoundingRectangle new.
			block := [:the | aBoundingBox expandToBound: (self uvAt: the)]].
	block value: theStart.
	block value: theEnd.
	"Include salient points."
	half_pi := Double pi / 2.0d.
	(theStart / half_pi) ceiling to: (theEnd / half_pi) floor
		do: [:i | block value: i * half_pi]</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox1">privateCalcBoundingBox1
	| n dthe |
	aBoundingBox := isSpatial 
				ifTrue: [CADSM.Misc.CADSMMiscBoundingBox new]
				ifFalse: [CADSM.Misc.CADSMMiscBoundingRectangle new].
	n := 16.
	dthe := (theEnd - theStart) / (n - 1).
	1 to: n
		do: 
			[:i | 
			| the |
			the := theStart + ((i - 1) * dthe).
			isSpatial 
				ifTrue: [aBoundingBox expandToBound: (self rfpfAt: the)]
				ifFalse: [aBoundingBox expandToBound: (self uvAt: the)]].
	1 to: 5
		do: 
			[:i | 
			"Include salient points."

			| the |
			the := (i - 1) * (Double pi / 2).
			(the ge: theStart le: theEnd) 
				ifTrue: 
					[isSpatial 
						ifTrue: [aBoundingBox expandToBound: (self rfpfAt: the)]
						ifFalse: [aBoundingBox expandToBound: (self uvAt: the)]]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoEllipticArc</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="printOn:">printOn: aStream 
	aStream nextPut: $a.
	aStream print: self class.
	aStream nextPut: $(.
	aStream
		cr;
		print: self rFstartF.
	aStream
		cr;
		print: self rFendF.
	aStream nextPut: $)</body>

<body package="CADSM-Geo" selector="printVerboseOn:">printVerboseOn: aStream 
	aStream
		nextPutAll: 'EllipticArc';
		cr;
		printVerbose: aRefFrame;
		cr;
		nextPutAll: 'xRadius = ';
		printVerbose: xRadius;
		cr;
		nextPutAll: 'yRadius = ';
		printVerbose: xRadius;
		cr;
		nextPutAll: 'theStart = ';
		printVerbose: theStart;
		cr;
		nextPutAll: 'theEnd = ';
		printVerbose: theEnd</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aNurbs">aNurbs
	^self</body>

<body package="CADSM-Geo" selector="atU:">atU: u 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller. 
	pp 124.
	"

	| uSpan cN numerator denominator ii nw |
	uSpan := self uspan_at: u.
	cN := self cNu_at: u uSpan: uSpan.
	numerator := StMFullColumn zero: self nDimension.
	denominator := 0.0d.
	0 to: uDegree
		do: 
			[:i | 
			ii := uSpan - uDegree + i.
			nw := (cN at: i + 1) * (cWeight at: ii).
			numerator equalSelfPlusFullColumn: (cPoint at: ii) times: nw.
			denominator := denominator + nw].
	^numerator / denominator</body>

<body package="CADSM-Geo" selector="cDeriv:u:">cDeriv: iDeriv u: u 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp 93 and 127.
	"

	| iDeriv1 nDimension iDerivu cDeriv cDerivP cDerivW uSpan ccDerivNu |
	iDeriv1 := iDeriv + 1.
	nDimension := self nDimension.
	iDerivu := iDeriv min: uDegree.
	cDeriv := StMFullColumn new: iDeriv1.
	cDerivP := StMFullColumn new: iDeriv1.
	cDerivW := StMFullColumn new: iDeriv1.
	uDegree + 1 to: iDeriv
		do: 
			[:i | 
			| i1 |
			i1 := i + 1.
			cDeriv at: i1 put: (StMFullColumn zero: nDimension).
			cDerivP at: i1 put: (StMFullColumn zero: nDimension).
			cDerivW at: i1 put: 0.0d].
	uSpan := self uspan_at: u.
	ccDerivNu := CADSMGeoNurbsCurve 
				ccDerivNu_at: u
				uDeriv: iDerivu
				uSpan: uSpan
				cuKnot: cuKnot
				uDegree: uDegree.
	0 to: iDerivu
		do: 
			[:i | 
			| i1 numerator denominator |
			i1 := i + 1.
			numerator := StMFullColumn zero: nDimension.
			denominator := 0.0d.
			0 to: uDegree
				do: 
					[:j | 
					| j1 jj nw |
					j1 := j + 1.
					jj := uSpan - uDegree + j.
					nw := (ccDerivNu at: i1 and: j1) * (cWeight at: jj).
					numerator equalSelfPlusFullColumn: (cPoint at: jj) times: nw.
					denominator := denominator + nw].
			cDerivP at: i1 put: numerator.
			cDerivW at: i1 put: denominator].
	0 to: iDeriv
		do: 
			[:i | 
			| i1 temp |
			i1 := i + 1.
			temp := cDerivP at: i1.
			1 to: i
				do: 
					[:j | 
					| j1 ij1 bw |
					j1 := j + 1.
					ij1 := i - j + 1.
					bw := ((CcBinomial at: i1) at: j1) negated * (cDerivW at: j1).
					temp equalSelfPlusFullColumn: (cDeriv at: ij1) times: bw].
			cDeriv at: i1 put: temp / (cDerivW at: 1)].
	^cDeriv</body>

<body package="CADSM-Geo" selector="cNu_at:uSpan:">cNu_at: u uSpan: uSpan 
	^CADSMGeoNurbsCurve 
		cNu_at: u
		uSpan: uSpan
		cuKnot: cuKnot
		uDegree: uDegree</body>

<body package="CADSM-Geo" selector="cPoint">cPoint
	^cPoint</body>

<body package="CADSM-Geo" selector="cPoint:">cPoint: anObject
	cPoint := anObject</body>

<body package="CADSM-Geo" selector="cuKnot">cuKnot
	^cuKnot</body>

<body package="CADSM-Geo" selector="cuKnot:">cuKnot: cDouble 
	cuKnot := cDouble</body>

<body package="CADSM-Geo" selector="cWeight">cWeight
	^cWeight</body>

<body package="CADSM-Geo" selector="cWeight:">cWeight: anObject
	cWeight := anObject</body>

<body package="CADSM-Geo" selector="derivative:at:">derivative: iDeriv at: u 
	^(self cDeriv: iDeriv u: u) at: iDeriv + 1</body>

<body package="CADSM-Geo" selector="nDimension">nDimension
	^cPoint first size</body>

<body package="CADSM-Geo" selector="order">order
	^uDegree + 1</body>

<body package="CADSM-Geo" selector="reverse">reverse
	| answer |
	answer := self class new.
	answer isSpatial: isSpatial.
	answer _cPoint: cPoint reverse.
	answer cWeight: cWeight reverse.
	answer _cuKnot: (cuKnot collect: [:knot | knot negated]) reverse.
	^answer</body>

<body package="CADSM-Geo" selector="rfpf_u:">rfpf_u: u 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller. 
	pp 124.
	"

	| uSpan cN numerator denominator ii nw |
	uSpan := self uspan_at: u.
	cN := self cNu_at: u uSpan: uSpan.
	numerator := StMFullColumn zero: self nDimension.
	denominator := 0.0d.
	0 to: uDegree
		do: 
			[:i | 
			ii := uSpan - uDegree + i.
			nw := (cN at: i + 1) * (cWeight at: ii).
			numerator equalSelfPlusFullColumn: (cPoint at: ii) times: nw.
			denominator := denominator + nw].
	^numerator / denominator</body>

<body package="CADSM-Geo" selector="show">show
	(self asJunOpenGL3dNurbsCurve)
		paint: ColorValue blue;
		show</body>

<body package="CADSM-Geo" selector="uDegree">uDegree
	^uDegree</body>

<body package="CADSM-Geo" selector="umax">umax
	^umax</body>

<body package="CADSM-Geo" selector="umin">umin
	^umin</body>

<body package="CADSM-Geo" selector="uspan_at:">uspan_at: u 
	^CADSMGeoNurbsCurve 
		uSpan_at: u
		cuKnot: cuKnot
		uDegree: uDegree</body>

<body package="CADSM-Geo" selector="_cPoint:">_cPoint: acPoint 
	cPoint := acPoint.
	self calcWPoint.
	self calc_uDegree</body>

<body package="CADSM-Geo" selector="_cuKnot:">_cuKnot: acuKnot 
	cuKnot := acuKnot.
	self calc_uDegree.
	umin := cuKnot first.
	umax := cuKnot last</body>

<body package="CADSM-Geo" selector="_cWeight:">_cWeight: acWeight 
	cWeight := acWeight.
	self calcWPoint</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	cPoint := cPoint copy.
	cWeight := cWeight copy.
	cuKnot := cuKnot copy</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="asJunOpenGL3dNurbsCurve">asJunOpenGL3dNurbsCurve
	^JunOpenGL3dNurbsCurve 
		controlPoints: (cPoint first size = 3 
				ifTrue: [cPoint copy]
				ifFalse: [cPoint collect: [:aPoint | aPoint copyWith: 0.0d]])
		weights: cWeight copy
		knotVector: cuKnot copy</body>

<body package="CADSM-Geo" selector="be2D">be2D
	cPoint := cPoint collect: [:aPoint | aPoint copyFrom: 1 to: 2]</body>

<body package="CADSM-Geo" selector="boundConicalSurface:">boundConicalSurface: aConicalSurface 
	aConicalSurface boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundCylindricalSurface:">boundCylindricalSurface: aCylindricalSurface 
	aCylindricalSurface boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundNurbsSurface:">boundNurbsSurface: aNurbsSurface 
	aNurbsSurface boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundRectSurface:">boundRectSurface: aRectSurface 
	aRectSurface boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundSphericalSurface:">boundSphericalSurface: aSphericalSurface 
	aSphericalSurface boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundSurfaceOfRevolution:">boundSurfaceOfRevolution: aSurfaceOfRevolution 
	aSurfaceOfRevolution boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundSweep:">boundSweep: aSweep 
	aSweep boundByNurbsCurve: self</body>

<body package="CADSM-Geo" selector="boundToroidalSurface:">boundToroidalSurface: aToroidalSurface 
	"Do nothing."

	</body>

<body package="CADSM-Geo" selector="cLineNurbs">cLineNurbs
	| n aPoint du bPoint aLineNurbs |
	n := 8.
	aPoint := self atU: umin.
	du := (umax - umin) / n.
	^(1 to: n) collect: 
			[:i | 
			bPoint := self atU: i * du.
			aLineNurbs := CADSMGeoNurbsCurve fromStart: aPoint copy toEnd: bPoint copy.
			aPoint := bPoint.
			aLineNurbs]</body>

<body package="CADSM-Geo" selector="conditionOpenGL">conditionOpenGL
	| tol |
	tol := 1.0d-9.
	cPoint conditionSelfWithTol: tol.
	cWeight conditionSelfWithTol: tol.
	cuKnot conditionSelfWithTol: tol</body>

<body package="CADSM-Geo" selector="conditionOpenGL1">conditionOpenGL1
	| tol |
	tol := 1.0d-9.
	cPoint conditionSelfWithTol: tol.
	cWeight conditionSelfWithTol: tol.
	cuKnot conditionSelfWithTol: tol</body>

<body package="CADSM-Geo" selector="conditionOpenGL2">conditionOpenGL2
	| tol magnification |
	tol := 1.0d-9.
	cPoint conditionSelfWithTol: tol.
	cWeight conditionSelfWithTol: tol.
	cuKnot conditionSelfWithTol: tol.
	magnification := 1.0d / (umax - umin).
	cuKnot := cuKnot collect: [:u | (u - umin) * magnification].
	umin := 0.0d.
	umax := 1.0d</body>

<body package="CADSM-Geo" selector="cuGuess">cuGuess
	| n du cuGuess |
	n := 9.
	du := (umax - umin) / (n - 1).
	cuGuess := OrderedCollection new: n.
	1 to: n
		do: 
			[:i | 
			| u |
			u := umin + ((i - 1) * du).
			cuGuess add: u].
	^cuGuess</body>

<body package="CADSM-Geo" selector="finalize_cuv">finalize_cuv
	self cuv ifNotNil: 
			[:cuv | 
			| newNurbsCurve |
			newNurbsCurve := CADSMGeoNurbsCurve fromcDataPoint: cuv uDegree: 1.
			self
				_cPoint: newNurbsCurve cPoint;
				cWeight: newNurbsCurve cWeight;
				_cuKnot: newNurbsCurve cuKnot;
				isSpatial: false;
				privateCalcBoundingBox]</body>

<body package="CADSM-Geo" selector="isOK">isOK
	^true</body>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	cPoint magnifySelf: aDouble</body>

<body package="CADSM-Geo" selector="normalizeKnots">normalizeKnots
	| magnification |
	magnification := 1.0d / (umax - umin).
	cuKnot := cuKnot collect: [:u | (u - umin) * magnification].
	umin := 0.0d.
	umax := 1.0d</body>

<body package="CADSM-Geo" selector="nPoint:">nPoint: n 
	| du answer |
	du := (umax - umin) / (n - 1).
	answer := (1 to: n) collect: 
					[:i | 
					| u |
					u := umin + ((i - 1) * du).
					self atU: u].
	answer changeClassToThatOf: StMFullColumn basicNew.
	^answer</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	self _cPoint: cPoint reverse.
	self cWeight: cWeight reverse.
	self _cuKnot: cuKnot negated reverse</body>

<body package="CADSM-Geo" selector="rFendF">rFendF
	^self rFpF_u: umax</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^self copy</body>

<body package="CADSM-Geo" selector="rFstartF">rFstartF
	^self rFpF_u: umin</body>

<body package="CADSM-Geo" selector="scaleF:">scaleF: uvwScale 
	cPoint do: [:aPoint | aPoint scaleSelfBy: uvwScale]</body>

<body package="CADSM-Geo" selector="transformSelfBy_rFfF:aAFf:">transformSelfBy_rFfF: rFfF aAFf: aAFf 
	| rFfF2D aAFf2D |
	cPoint := isSpatial 
				ifTrue: 
					[cPoint 
						collect: [:aPoint | rFfF plusFullColumn: (aAFf timesFullColumn: aPoint)]]
				ifFalse: 
					[rFfF2D := rFfF copyFrom: 1 to: 2.
					aAFf2D := StMFullMatrix new: 2 by: 2.
					aAFf2D equalFullMatrix: aAFf.
					cPoint 
						collect: [:aPoint | rFfF2D plusFullColumn: (aAFf2D timesFullColumn: aPoint)]]</body>

<body package="CADSM-Geo" selector="uend">uend
	^isSpatial ifTrue: [self halt: 'Check this'] ifFalse: [(self atU: umax) u]</body>

<body package="CADSM-Geo" selector="uOfPoint:">uOfPoint: rFpF 
	| dist newdist uGuess |
	dist := StMMachineAccuracy OfLargestDouble.
	self cuGuess do: 
			[:aGuess | 
			newdist := (rFpF minusFullColumn: (self atU: aGuess)) length.
			newdist &lt; dist 
				ifTrue: 
					[dist := newdist.
					uGuess := aGuess]].
	^self uOfPoint: rFpF uGuess: uGuess</body>

<body package="CADSM-Geo" selector="uOfPoint:uGuess:">uOfPoint: rFpF uGuess: uGuess 
	^(NurbsCurveInversion new)
		rFpF: rFpF;
		x: uGuess;
		system: self;
		run;
		x</body>

<body package="CADSM-Geo" selector="uvBound">uvBound
	self assert: [isSpatial not].
	^aBoundingBox</body>

<body package="CADSM-Geo" selector="uvCurveOnSurface:">uvCurveOnSurface: aSurface 
	| aaCurve |
	aaCurve := aSurface uvCurveOfNurbsCurve: self.
"	aSurface condition_cuv: aaCurve."
	^aaCurve</body>

<body package="CADSM-Geo" selector="uvCurveOnSurface:preCurve:">uvCurveOnSurface: aSurface preCurve: preCurve 
	^aSurface uvCurveOfNurbsCurve: self preCurve: preCurve</body>

<body package="CADSM-Geo" selector="uvEnd">uvEnd
	self assert: [isSpatial not].
	^self atU: umax</body>

<body package="CADSM-Geo" selector="uvend">uvend
	^isSpatial ifTrue: [self halt: 'Check this'] ifFalse: [self atU: umax]</body>

<body package="CADSM-Geo" selector="uvShift:">uvShift: uvShift 
	self cuv do: [:uv | uv equalSelfPlus: uvShift]</body>

<body package="CADSM-Geo" selector="uvStart">uvStart
	self assert: [isSpatial not].
	^self atU: umin</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>comparing</category>

<body package="CADSM-Geo" selector="=">= aObject 
	^self == aObject or: 
			[self class == aObject class and: 
					[| block |
					block := 
							[:ca :cb | 
							ca size = cb size ifFalse: [^false].
							ca with: cb parallelDo: [:a :b | (a - b) length &lt; 1.0d-9 ifFalse: [^false]]].
					block value: self cPoint value: aObject cPoint.
					block value: self cWeight value: aObject cWeight.
					block value: self cuKnot value: aObject cuKnot.
					true]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="calcWPoint">calcWPoint
	cWPoint := cPoint ifNotNil: 
					[cWeight ifNotNil: 
							[cPoint with: cWeight
								parallelCollect: [:aPoint :aWeight | (aPoint times: aWeight) copyWith: aWeight]]]</body>

<body package="CADSM-Geo" selector="calc_uDegree">calc_uDegree
	cPoint 
		ifNotNil: [cuKnot ifNotNil: [uDegree := cuKnot size - cPoint size - 1]]</body>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	| n |
	aBoundingBox := isSpatial 
				ifTrue: [CADSM.Misc.CADSMMiscBoundingBox new]
				ifFalse: [CADSM.Misc.CADSMMiscBoundingRectangle new].
	n := cPoint size max: 128.
	umin to: umax
		by: (umax - umin) / n
		do: [:u | aBoundingBox expandToBound: (self atU: u)]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="printOn:">printOn: aStream 
	aStream nextPut: $a.
	aStream print: self class.
	aStream nextPut: $(.
	aStream print: cPoint.
	aStream nextPut: $)</body>

<body package="CADSM-Geo" selector="printVerboseOn:">printVerboseOn: aStream 
	aStream
		nextPutAll: 'NurbsCurve';
		cr;
		nextPutAll: 'cPoint = ';
		cr.
	cPoint do: 
			[:a | 
			aStream
				print: a;
				cr].
	aStream
		nextPutAll: 'cWeight = ';
		print: cWeight;
		cr;
		nextPutAll: 'cuKnot = ';
		print: cuKnot</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="fromEllipse:">fromEllipse: aEllipse 
	| answer xRadius yRadius mxRadius myRadius cPoint cWeight oneOverRootTwo cuKnot |
	answer := self new.
	answer isSpatial: aEllipse isSpatial.
	xRadius := aEllipse xRadius.
	yRadius := aEllipse yRadius.
	mxRadius := xRadius negated.
	myRadius := yRadius negated.
	cPoint := StMArray new: 9.
	cPoint at: 1
		put: (StMFullColumn 
				with: xRadius
				with: 0.0d
				with: 0.0d).
	cPoint at: 2
		put: (StMFullColumn 
				with: xRadius
				with: yRadius
				with: 0.0d).
	cPoint at: 3
		put: (StMFullColumn 
				with: 0.0d
				with: yRadius
				with: 0.0d).
	cPoint at: 4
		put: (StMFullColumn 
				with: mxRadius
				with: yRadius
				with: 0.0d).
	cPoint at: 5
		put: (StMFullColumn 
				with: mxRadius
				with: 0.0d
				with: 0.0d).
	cPoint at: 6
		put: (StMFullColumn 
				with: mxRadius
				with: myRadius
				with: 0.0d).
	cPoint at: 7
		put: (StMFullColumn 
				with: 0.0d
				with: myRadius
				with: 0.0d).
	cPoint at: 8
		put: (StMFullColumn 
				with: xRadius
				with: myRadius
				with: 0.0d).
	cPoint at: 9
		put: (StMFullColumn 
				with: xRadius
				with: 0.0d
				with: 0.0d).
	answer _cPoint: cPoint.
	cWeight := StMArray new: 9.
	oneOverRootTwo := 1 / 2.0d sqrt.
	cWeight at: 1 put: 1.0d.
	cWeight at: 2 put: oneOverRootTwo.
	cWeight at: 3 put: 1.0d.
	cWeight at: 4 put: oneOverRootTwo.
	cWeight at: 5 put: 1.0d.
	cWeight at: 6 put: oneOverRootTwo.
	cWeight at: 7 put: 1.0d.
	cWeight at: 8 put: oneOverRootTwo.
	cWeight at: 9 put: 1.0d.
	answer cWeight: cWeight.
	cuKnot := StMArray new: 12.
	cuKnot at: 1 put: 0.0d.
	cuKnot at: 2 put: 0.0d.
	cuKnot at: 3 put: 0.0d.
	cuKnot at: 4 put: 0.25d.
	cuKnot at: 5 put: 0.25d.
	cuKnot at: 6 put: 0.5d.
	cuKnot at: 7 put: 0.5d.
	cuKnot at: 8 put: 0.75d.
	cuKnot at: 9 put: 0.75d.
	cuKnot at: 10 put: 1.0d.
	cuKnot at: 11 put: 1.0d.
	cuKnot at: 12 put: 1.0d.
	answer _cuKnot: cuKnot.
	^answer</body>

<body package="CADSM-Geo" selector="fromEllipticArc:">fromEllipticArc: aEllipticArc 
	"Refer to Nurbs Book pp 310."

	| theStart theEnd nseg ndegree dthe cPoint cWeight cuKnot aSmallEllipticArc aNurbs answer |
	theStart := aEllipticArc theStart.
	theEnd := aEllipticArc theEnd.
	nseg := ((theEnd - theStart) / Double halfPi) ceiling.
	ndegree := 2.
	dthe := (theEnd - theStart) / nseg.
	cPoint := (StMArray new: nseg * ndegree + 1) writeStream.
	cWeight := (StMArray new: nseg * ndegree + 1) writeStream.
	cuKnot := (StMArray new: (nseg + 1) * ndegree + 2) writeStream.
	aSmallEllipticArc := aEllipticArc copy.
	aSmallEllipticArc theStart: theStart.
	aSmallEllipticArc theEnd: theStart + dthe.
	self assert: [aSmallEllipticArc isOK].
	aNurbs := self fromSmallEllipticArc: aSmallEllipticArc.
	1 to: ndegree + 1
		do: 
			[:i | 
			cPoint nextPut: (aNurbs cPoint at: i).
			cWeight nextPut: (aNurbs cWeight at: i).
			cuKnot nextPut: 0.0d].
	2 to: nseg
		do: 
			[:i | 
			aSmallEllipticArc := aEllipticArc copy.
			aSmallEllipticArc theStart: theStart + ((i - 1) * dthe).
			aSmallEllipticArc theEnd: theStart + (i * dthe).
			self assert: [aSmallEllipticArc isOK].
			aNurbs := self fromSmallEllipticArc: aSmallEllipticArc.
			1 to: ndegree
				do: 
					[:ii | 
					cPoint nextPut: (aNurbs cPoint at: 1 + ii).
					cWeight nextPut: (aNurbs cWeight at: 1 + ii).
					cuKnot nextPut: ((i - 1) / nseg) asDouble]].
	ndegree + 1 timesRepeat: [cuKnot nextPut: 1.0d].
	answer := self new.
	answer isSpatial: aEllipticArc isSpatial.
	answer _cPoint: cPoint contents.
	answer cWeight: cWeight contents.
	answer _cuKnot: cuKnot contents.
	^answer</body>

<body package="CADSM-Geo" selector="fromLine:">fromLine: aLine 
	| answer cPoint cWeight cuKnot |
	answer := self new.
	answer isSpatial: aLine isSpatial.
	cPoint := StMArray with: aLine rfstartf with: aLine rfendf.
	answer _cPoint: cPoint.
	cWeight := StMArray with: 1.0d with: 1.0d.
	answer cWeight: cWeight.
	cuKnot := #(0.0d 0.0d 1.0d 1.0d).
	answer _cuKnot: cuKnot copy.
	^answer</body>

<body package="CADSM-Geo" selector="fromSmallEllipticArc:">fromSmallEllipticArc: aEllipticArc 
	"
	Refer to Nurbs Book pp 310.
	Subtended angle is =&lt; 120 degrees.
	"

	| theStart theEnd p0 p2 t0 t2 p v02 array p1 v1p alf0 alf2 a u num den w1 answer cPoint cWeight cuKnot |
	theStart := aEllipticArc theStart.
	theEnd := aEllipticArc theEnd.
	p0 := aEllipticArc rfpfAt: theStart.
	p2 := aEllipticArc rfpfAt: theEnd.
	t0 := aEllipticArc tangentAt: theStart.
	t2 := aEllipticArc tangentAt: theEnd.
	p := aEllipticArc rfpfAt: (theStart + theEnd) / 2.0d.
	v02 := p2 - p0.
	array := CADSMGeoLine 
				dataIntersectionPoint: p0
				aDir: t0
				bPoint: p2
				bDir: t2
				tolerance: 1.0d-9.
	self assert: [array first]
		do: 
			[p1 := array at: 2.
			v1p := p - p1.
			array := CADSMGeoLine 
						dataIntersectionPoint: p1
						aDir: v1p
						bPoint: p0
						bDir: v02
						tolerance: 1.0d-9.
			self assert: [array first]
				do: 
					[alf0 := array at: 3.
					alf2 := array at: 4.
					a := (alf2 / (1.0d - alf2)) sqrt.
					u := a / (1.0d + a).
					num := (1.0d - u) squared * (p - p0 dot: p1 - p) 
								+ (u squared * (p - p2 dot: p1 - p)).
					den := 2.0d * u * (1.0d - u) * (p1 - p) sumOfSquares.
					w1 := num / den]].
	answer := self new.
	answer isSpatial: aEllipticArc isSpatial.
	cPoint := StMArray 
				with: p0
				with: p1
				with: p2.
	cWeight := StMArray 
				with: 1.0d
				with: w1
				with: 1.0d.
	cuKnot := StMArray new: 6.
	cuKnot at: 1 put: 0.0d.
	cuKnot at: 2 put: 0.0d.
	cuKnot at: 3 put: 0.0d.
	cuKnot at: 4 put: 1.0d.
	cuKnot at: 5 put: 1.0d.
	cuKnot at: 6 put: 1.0d.
	answer _cPoint: cPoint.
	answer cWeight: cWeight.
	answer _cuKnot: cuKnot.
	^answer</body>

<body package="CADSM-Geo" selector="fromStart:toEnd:">fromStart: aStart toEnd: aEnd 
	| answer cPoint cWeight cuKnot |
	answer := self new.
	cPoint := StMArray with: aStart with: aEnd.
	answer _cPoint: cPoint.
	cWeight := StMArray with: 1.0d with: 1.0d.
	answer cWeight: cWeight.
	cuKnot := #(0.0d 0.0d 1.0d 1.0d).
	answer _cuKnot: cuKnot copy.
	^answer</body>

<body package="CADSM-Geo" selector="fromStart:toEnd:isSpatial:">fromStart: aStart toEnd: aEnd isSpatial: boolean 
	| answer cPoint cWeight cuKnot |
	answer := self new.
	cPoint := StMArray with: aStart with: aEnd.
	answer _cPoint: cPoint.
	cWeight := StMArray with: 1.0d with: 1.0d.
	answer cWeight: cWeight.
	cuKnot := #(0.0d 0.0d 1.0d 1.0d).
	answer _cuKnot: cuKnot copy.
	answer isSpatial: boolean.
	^answer</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve class</class-id> <category>examples</category>

<body package="CADSM-Geo" selector="example1">example1
	"NurbsCurve example1"

	| answer |
	answer := self exampleCircle.
	answer atU: -1.0d.
	answer atU: -0.5d.
	answer atU: 0.0d.
	answer atU: 0.5d.
	answer atU: 1.0d.
	answer atU: 1.5d.
	answer atU: 2.0d.
	answer atU: 2.5d.
	answer atU: 3.0d.
	answer atU: 3.5d.
	answer atU: 4.0d.
	answer atU: 4.5d.
	answer atU: 5.0d</body>

<body package="CADSM-Geo" selector="example2">example2
	"NurbsCurve example2"

	| answer |
	answer := self exampleCircle.
	answer derivative: 1 at: -1.0d.
	answer derivative: 1 at: -0.5d.
	answer derivative: 1 at: 0.0d.
	answer derivative: 1 at: 0.5d.
	answer derivative: 1 at: 1.0d.
	answer derivative: 1 at: 1.5d.
	answer derivative: 1 at: 2.0d.
	answer derivative: 1 at: 2.5d.
	answer derivative: 1 at: 3.0d.
	answer derivative: 1 at: 3.5d.
	answer derivative: 1 at: 4.0d.
	answer derivative: 1 at: 4.5d.
	answer derivative: 1 at: 5.0d</body>

<body package="CADSM-Geo" selector="example2a">example2a
	"NurbsCurve example2a"

	| answer |
	answer := self exampleLine.
	answer derivative: 1 at: -1.0d.
	answer derivative: 1 at: -0.5d.
	answer derivative: 1 at: 0.0d.
	answer derivative: 1 at: 0.5d.
	answer derivative: 1 at: 1.0d.
	answer derivative: 1 at: 1.5d.
	answer derivative: 1 at: 2.0d.
	answer derivative: 1 at: 2.5d.
	answer derivative: 1 at: 3.0d.
	answer derivative: 1 at: 3.5d.
	answer derivative: 1 at: 4.0d.
	answer derivative: 1 at: 4.5d.
	answer derivative: 1 at: 5.0d</body>

<body package="CADSM-Geo" selector="example2b">example2b
	"NurbsCurve example2b"

	| answer |
	answer := self exampleTest.
	answer derivative: 2 at: 2.5d</body>

<body package="CADSM-Geo" selector="exampleCircle">exampleCircle
	"NurbsCurve exampleCircle"

	| cPoint cWeight cuKnot |
	cPoint := Array new: 9.
	cPoint at: 1 put: (0 , -1 , 0) asFullColumn.
	cPoint at: 2 put: (1 , -1 , 0) asFullColumn.
	cPoint at: 3 put: (1 , 0 , 0) asFullColumn.
	cPoint at: 4 put: (1 , 1 , 0) asFullColumn.
	cPoint at: 5 put: (0 , 1 , 0) asFullColumn.
	cPoint at: 6 put: (-1 , 1 , 0) asFullColumn.
	cPoint at: 7 put: (-1 , 0 , 0) asFullColumn.
	cPoint at: 8 put: (-1 , -1 , 0) asFullColumn.
	cPoint at: 9 put: (0 , -1 , 0) asFullColumn.
	cWeight := Array new: 9.
	cWeight at: 1 put: 1.0d.
	cWeight at: 2 put: 1 / 2.0d sqrt.
	cWeight at: 3 put: 1.0d.
	cWeight at: 4 put: 1 / 2.0d sqrt.
	cWeight at: 5 put: 1.0d.
	cWeight at: 6 put: 1 / 2.0d sqrt.
	cWeight at: 7 put: 1.0d.
	cWeight at: 8 put: 1 / 2.0d sqrt.
	cWeight at: 9 put: 1.0d.
	cuKnot := #(0 0 0 1 1 2 2 3 3 4 4 4).
	^(self new)
		_cPoint: cPoint;
		cWeight: cWeight;
		_cuKnot: cuKnot;
		yourself</body>

<body package="CADSM-Geo" selector="exampleEllipticArc">exampleEllipticArc
	"NurbsCurve exampleEllipticArc"

	| aEllipticArc aNurbs |
	aEllipticArc := (CADSM.Geo.CADSMGeoEllipticArc new)
				xRadius: 1.0d;
				yRadius: 2.0d;
				theStart: 0.0d;
				theEnd: 1.5d * Double pi;
				yourself.
	aNurbs := CADSMGeoNurbsCurve fromEllipticArc: aEllipticArc.
	aNurbs asJunOpenGL3dNurbsCurve show</body>

<body package="CADSM-Geo" selector="exampleLine">exampleLine
	"NurbsCurve exampleLine"

	| cPoint cWeight cuKnot |
	cPoint := Array new: 2.
	cPoint at: 1 put: (0 , 0 , 0) asFullColumn.
	cPoint at: 2 put: (1 , 1 , 0) asFullColumn.
	cWeight := Array new: 2.
	cWeight at: 1 put: 1.0d.
	cWeight at: 2 put: 1.0d.
	cuKnot := #(0 0 1 1).
	^(self new)
		_cPoint: cPoint;
		cWeight: cWeight;
		_cuKnot: cuKnot;
		yourself</body>

<body package="CADSM-Geo" selector="exampleTest">exampleTest
	"NurbsCurve exampleTest"

	| cPoint cWeight cuKnot |
	cPoint := Array new: 8.
	cPoint at: 1 put: (0 , 0 , 0) asFullColumn.
	cPoint at: 2 put: (1 , 1 , 0) asFullColumn.
	cPoint at: 3 put: (0 , 0 , 0) asFullColumn.
	cPoint at: 4 put: (1 , 1 , 0) asFullColumn.
	cPoint at: 5 put: (0 , 0 , 0) asFullColumn.
	cPoint at: 6 put: (1 , 1 , 0) asFullColumn.
	cPoint at: 7 put: (0 , 0 , 0) asFullColumn.
	cPoint at: 8 put: (1 , 1 , 0) asFullColumn.
	cWeight := Array new: 8.
	cWeight at: 1 put: 1.0d.
	cWeight at: 2 put: 1.0d.
	cWeight at: 3 put: 1.0d.
	cWeight at: 4 put: 1.0d.
	cWeight at: 5 put: 1.0d.
	cWeight at: 6 put: 1.0d.
	cWeight at: 7 put: 1.0d.
	cWeight at: 8 put: 1.0d.
	cuKnot := #(0 0 0 1 2 3 4 4 5 5 5).
	^(self new)
		_cPoint: cPoint;
		cWeight: cWeight;
		_cuKnot: cuKnot;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve class</class-id> <category>class initialization</category>

<body package="CADSM-Geo" selector="initialize">initialize
	"self initialize."

	| n aRow previousRow |
	n := 10.
	CcBinomial := StMArray new: n.
	aRow := StMFullRow new: 1.
	aRow at: 1 put: 1.
	CcBinomial at: 1 put: aRow.
	previousRow := aRow.
	2 to: n
		do: 
			[:i | 
			aRow := StMFullRow new: i.
			aRow at: 1 put: 1.
			2 to: i - 1
				do: [:j | aRow at: j put: (previousRow at: j - 1) + (previousRow at: j)].
			aRow at: i put: 1.
			CcBinomial at: i put: aRow.
			previousRow := aRow].
	^CcBinomial</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve class</class-id> <category>utilities</category>

<body package="CADSM-Geo" selector="ccDerivNu_at:uDeriv:uSpan:cuKnot:uDegree:">ccDerivNu_at: u uDeriv: uDeriv uSpan: uSpan cuKnot: cuKnot uDegree: uDegree 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp. 72
	"

	| uDegree1 ccDerivN ccNdu ccA left right uSpan1 product |
	uDegree1 := uDegree + 1.
	ccDerivN := StMFullMatrix new: uDeriv + 1 by: uDegree1.
	ccNdu := StMFullMatrix new: uDegree1 by: uDegree1.
	ccA := StMFullMatrix new: 2 by: uDegree1.
	left := StMArray new: uDegree.
	right := StMArray new: uDegree.
	uSpan1 := uSpan + 1.
	ccNdu 
		at: 1
		and: 1
		put: 1.0d.
	1 to: uDegree
		do: 
			[:i | 
			| ii saved |
			left at: i put: u - (cuKnot at: uSpan1 - i).
			right at: i put: (cuKnot at: uSpan + i) - u.
			saved := 0.0d.
			ii := i + 1.
			0 to: i - 1
				do: 
					[:j | 
					| jj rightjj leftij aNduij temp |
					jj := j + 1.
					rightjj := right at: jj.
					leftij := left at: i - j.
					aNduij := rightjj + leftij.
					ccNdu 
						at: ii
						and: jj
						put: aNduij.
					temp := (ccNdu at: jj and: i) / aNduij.
					ccNdu 
						at: jj
						and: ii
						put: saved + (rightjj * temp).
					saved := leftij * temp].
			ccNdu 
				at: ii
				and: ii
				put: saved].
	0 to: uDegree
		do: 
			[:i | 
			| ii |
			ii := i + 1.
			ccDerivN 
				at: 1
				and: ii
				put: (ccNdu at: ii and: uDegree1)].
	0 to: uDegree
		do: 
			[:i | 
			| ii s1 s2 |
			ii := i + 1.
			s1 := 1.
			s2 := 2.
			ccA 
				at: 1
				and: 1
				put: 1.0d.
			1 to: uDeriv
				do: 
					[:j | 
					| jj d ij ij1 pj pj1 k1 k2 tmp |
					jj := j + 1.
					d := 0.0d.
					ij := i - j.
					ij1 := ij + 1.
					pj := uDegree - j.
					pj1 := pj + 1.
					i &gt;= j 
						ifTrue: 
							[| temp |
							temp := (ccA at: s1 and: 1) / (ccNdu at: pj1 + 1 and: ij1).
							ccA 
								at: s2
								and: 1
								put: temp.
							d := temp * (ccNdu at: ij1 and: pj1)].
					k1 := ij &gt;= -1 ifTrue: [1] ifFalse: [ij negated].
					k2 := i - 1 &lt;= pj ifTrue: [j - 1] ifFalse: [uDegree - i].
					k1 to: k2
						do: 
							[:k | 
							| kk ijk1 temp |
							kk := k + 1.
							ijk1 := ij1 + k.
							temp := ((ccA at: s1 and: kk) - (ccA at: s1 and: k)) 
										/ (ccNdu at: pj1 + 1 and: ijk1).
							ccA 
								at: s2
								and: kk
								put: temp.
							d := d + (temp * (ccNdu at: ijk1 and: pj1))].
					i &lt;= pj 
						ifTrue: 
							[| temp |
							temp := (ccA at: s1 and: j) negated / (ccNdu at: pj1 + 1 and: ii).
							ccA 
								at: s2
								and: jj
								put: temp.
							d := d + (temp * (ccNdu at: ii and: pj1))].
					ccDerivN 
						at: jj
						and: ii
						put: d.
					tmp := s1.
					s1 := s2.
					s2 := tmp]].
	product := uDegree.
	1 to: uDeriv
		do: 
			[:i | 
			| ii |
			ii := i + 1.
			0 to: uDegree
				do: 
					[:j | 
					| jj |
					jj := j + 1.
					ccDerivN 
						at: ii
						and: jj
						put: product * (ccDerivN at: ii and: jj)].
			product := product * (uDegree - i)].
	^ccDerivN</body>

<body package="CADSM-Geo" selector="cNu_at:uSpan:cuKnot:uDegree:">cNu_at: u uSpan: uSpan cuKnot: cuKnot uDegree: uDegree 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp. 70
	"

	| cN left right uSpan1 |
	cN := StMArray new: uDegree + 1.
	left := StMArray new: uDegree.
	right := StMArray new: uDegree.
	uSpan1 := uSpan + 1.
	cN at: 1 put: 1.0d.
	1 to: uDegree
		do: 
			[:i | 
			| saved |
			left at: i put: u - (cuKnot at: uSpan1 - i).
			right at: i put: (cuKnot at: uSpan + i) - u.
			saved := 0.0d.
			0 to: i - 1
				do: 
					[:j | 
					| jj rightjj leftij temp |
					jj := j + 1.
					rightjj := right at: jj.
					leftij := left at: i - j.
					temp := (cN at: jj) / (rightjj + leftij).
					cN at: jj put: saved + (rightjj * temp).
					saved := leftij * temp].
			cN at: i + 1 put: saved].
	^cN</body>

<body package="CADSM-Geo" selector="uSpan_at:cuKnot:uDegree:">uSpan_at: u cuKnot: cuKnot uDegree: uDegree 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp. 68
	"

	| iFirst iLast iLast1 iLow iHigh iMiddle |
	iFirst := uDegree + 1.
	iLast := cuKnot size - iFirst.
	iLast1 := iLast + 1.
	^u = (cuKnot at: iLast1) 
		ifTrue: [iLast]
		ifFalse: 
			[iLow := iFirst.
			iHigh := iLast1.
			
			[iMiddle := (iLow + iHigh) // 2.
			iLow = iMiddle] whileFalse: 
						[u &lt; (cuKnot at: iMiddle) 
							ifTrue: [iHigh := iMiddle]
							ifFalse: [iLow := iMiddle]].
			iLow]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve class</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="aMatrixNu_cu:cuKnot:uDegree:">aMatrixNu_cu: cu cuKnot: cuKnot uDegree: uDegree 
	"
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp. 70, 369
	"

	| nPoint aMatrixNu |
	nPoint := cu size.
	aMatrixNu := StMSparseMatrix new: nPoint by: nPoint.
	0 to: nPoint - 1
		do: 
			[:i | 
			| i1 rowi1 u uSpan cNu |
			i1 := i + 1.
			rowi1 := aMatrixNu at: i1.
			u := cu at: i1.
			uSpan := self 
						uSpan_at: u
						cuKnot: cuKnot
						uDegree: uDegree.
			cNu := self 
						cNu_at: u
						uSpan: uSpan
						cuKnot: cuKnot
						uDegree: uDegree.
			0 to: uDegree
				do: 
					[:j | 
					| jj |
					jj := uSpan - uDegree + j.
					rowi1 at: jj put: (cNu at: j + 1)]].
	^aMatrixNu</body>

<body package="CADSM-Geo" selector="CcBinomial">CcBinomial
	^CcBinomial</body>

<body package="CADSM-Geo" selector="cuKnot_cu:uDegree:">cuKnot_cu: cu uDegree: uDegree 
	| nPoint uDegree1 nKnot cKnot |
	nPoint := cu size.
	uDegree1 := uDegree + 1.
	nKnot := nPoint + uDegree1.
	cKnot := StMFullColumn new: nKnot.
	0 to: uDegree
		do: 
			[:i | 
			cKnot at: i + 1 put: 0.0d.
			cKnot at: nKnot - i put: 1.0d].
	1 to: nPoint - 1 - uDegree
		do: 
			[:i | 
			| sum |
			sum := 0.0d.
			i to: i + uDegree - 1 do: [:j | sum := sum + (cu at: j + 1)].
			cKnot at: i + uDegree1 put: sum / uDegree].
	^cKnot</body>

<body package="CADSM-Geo" selector="cu_cDataPoint:">cu_cDataPoint: cDataPoint 
	| n cdelta d cu u |
	n := cDataPoint size.
	cdelta := cDataPoint shallowCopy.
	d := 0.0d.
	2 to: n
		do: 
			[:i | 
			| delta |
			delta := ((cDataPoint at: i) - (cDataPoint at: i - 1)) length.
			cdelta at: i put: delta.
			d := d + delta].
	cu := cDataPoint shallowCopy.
	cu at: 1 put: 0.0d.
	cu at: n put: 1.0d.
	u := 0.0d.
	2 to: n - 1
		do: 
			[:i | 
			u := u + ((cdelta at: i) / d).
			cu at: i put: u].
	^cu</body>

<body package="CADSM-Geo" selector="fromcControlPoint:uDegree:">fromcControlPoint: cControlPoint uDegree: uDegree 
	"Quasi Uniform B-Spline"

	| nPoint nKnot nEndKnot nMidKnot cuKnot cWeight |
	nPoint := cControlPoint size.
	nKnot := nPoint + uDegree + 1.
	nEndKnot := uDegree + 1.
	nMidKnot := nKnot - (2 * nEndKnot).
	cuKnot := OrderedCollection new: nKnot.
	nEndKnot timesRepeat: [cuKnot add: 0.0d].
	1 to: nMidKnot do: [:i | cuKnot add: i asDouble].
	nEndKnot timesRepeat: [cuKnot add: nMidKnot + 1.0d].
	cWeight := cControlPoint shallowCopy atAllPut: 1.0d.
	^(self new)
		_cPoint: cControlPoint;
		cWeight: cWeight;
		_cuKnot: cuKnot;
		yourself</body>

<body package="CADSM-Geo" selector="fromcDataPoint:uDegree:">fromcDataPoint: cDataPoint uDegree: uDegree 
	"Interpolate thru cDataPoint.
	Ref: The NURBS Book, 2nd Ed. by Les Piegl and Wayne Tiller.
	pp 369
	"

	| cu cuKnot aMatrix cPoint cWeight |
	cu := self cu_cDataPoint: cDataPoint.
	cuKnot := self cuKnot_cu: cu uDegree: uDegree.
	aMatrix := self 
				aMatrixNu_cu: cu
				cuKnot: cuKnot
				uDegree: uDegree.
	cPoint := StMGESpMatParPvMarkoFast3 new 
				solve: aMatrix
				with: cDataPoint asFullColumn
				saveOriginal: false.
	cWeight := (cPoint shallowCopy)
				atAllPut: 1.0d;
				yourself.
	^(self new)
		_cPoint: cPoint;
		cWeight: cWeight;
		_cuKnot: cuKnot;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPolyline</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsCurve fromPolyline: self</body>

<body package="CADSM-Geo" selector="crFpointF">crFpointF
	^self crfpointf collect: [:rfpointf | aRefFrame rFpFfromrfpf: rfpointf]</body>

<body package="CADSM-Geo" selector="crfpointf">crfpointf
	^crfpointf</body>

<body package="CADSM-Geo" selector="crfpointf:">crfpointf: cPoint 
	crfpointf := cPoint.
	isClosed := crfpointf first = crfpointf last.
	self changed</body>

<body package="CADSM-Geo" selector="rfpointsf">rfpointsf
	^crfpointf</body>

<body package="CADSM-Geo" selector="rfpointsf:">rfpointsf: array 
	crfpointf := array.
	isClosed := crfpointf first = crfpointf last.
	self changed</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPolyline</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox new.
	crfpointf do: [:rfpointf | aBoundingBox expandToBound: rfpointf]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCircle</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="radius:">radius: r 
	xRadius := r abs.
	yRadius := xRadius.
	self changed</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCircle</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	aRefFrame rotatex: Double pi.
	^self</body>

<body package="CADSM-Geo" selector="_radius">_radius
	^xRadius</body>

<body package="CADSM-Geo" selector="_radius:">_radius: radius 
	xRadius := radius.
	yRadius := radius</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRotationalMotion</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| phiFunc parser stack func mbdZRotation |
	super createMbD.
	phiFunc := phiIJ isNil
				ifTrue: [StMConstant with: 0]
				ifFalse: [phiIJ isUserFunction
						ifTrue: 
							[parser := self functionParser.
							stack := parser
										parseUserFunction: phiIJ
										notifying: nil
										ifFail: nil.
							func := stack last.
							func]
						ifFalse: [phiIJ]].
	phiFunc := (phiFunc / self aMbDUnits angle) createMbD simplified.
	mbdZRotation := self mbdObject.
	mbdZRotation phiBlk: phiFunc</body>

<body package="CADSM-Geo" selector="phiFunc">phiFunc
	| parser stack func |
	^phiIJ isNil
		ifTrue: [StMConstant with: 0]
		ifFalse: [phiIJ isUserFunction
				ifTrue: 
					[parser := self functionParser.
					stack := parser
								parseUserFunction: phiIJ
								notifying: nil
								ifFail: nil.
					func := stack last.
					func]
				ifFalse: [phiIJ]]</body>

<body package="CADSM-Geo" selector="validateFormulas">validateFormulas
	self phiFunc</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRotationalMotion</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="eqnLabel">eqnLabel
	^'Rotation Motion Function'</body>

<body package="CADSM-Geo" selector="explainText">explainText
	^#'The motion constraint takes a prescribed function of time. It can accept a smooth expression created with the following operators or functions: +, -, *, /, ^ (raised to), pi, (-pi/2 &lt;= arctan(x) &lt;= pi/2), (-pi &lt;= arctan2(x,y) &lt;= pi), cos(x), exp(x), lg(x) (log base 10), ln(x) (natural log), sin(x), sqrt(x), tan(x).

You can cut, paste and modify the example functions below for use in the User Function Dialog.

Constant value function:
60.0d

Linear function with offset, 60.0d, and slope, 2.0d:
60.0d + 2.0d*time

Polynomial expression:
60.0d + 2.0d*time + 1.0d*time^2 + 0.1d*time^3

Simple harmonic motion with offset, 60.0d, amplitude, 2.0d, angular velocity, 6.0d*pi, phase lag, pi/4.0d:
60.0d + 2.0d*sin(6.0d*pi*time - pi/4.0d)

Exponential decay with initial value, 10.0d, time constant, 1.0d2:
10.0d*exp(-time/1.0d2)

CAD: Copyright (C) 2001, Aik-Siong Koh, All Rights Reserved.
'</body>

<body package="CADSM-Geo" selector="explainTitle">explainTitle
	^'Rotation Motion Function'</body>

<body package="CADSM-Geo" selector="joint">joint
	^self interface jointList detect: [:joint | ((joint isMemberOf: CADSMGeoRevoluteJoint)
			or: [joint isMemberOf: CADSMGeoCylindricalJoint])
			and: [joint aMarkerI == aMarkerI and: [joint aMarkerJ == aMarkerJ]]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRotationalMotion</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	aStream storeLevel: level title: self nameString.
	aStream
		storeLevel: level + 1
		title: 'Name'
		object: self name.
	aStream
		storeLevel: level + 1
		title: 'MotionJoint'
		object: self joint fullName.
	aStream
		storeLevel: level + 1
		title: 'RotationZ'
		object: phiIJ</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRotationalMotion class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDZRotation</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'RotationalMotion'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRectangle</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="crfpointf">crfpointf
	| crfpointf |
	crfpointf := StMArray new: 5.
	crfpointf at: 1 put: (StMFullColumn zero: 3).
	crfpointf at: 2
		put: (StMFullColumn 
				with: xLength
				with: 0.0d
				with: 0.0d).
	crfpointf at: 3
		put: (StMFullColumn 
				with: xLength
				with: yLength
				with: 0.0d).
	crfpointf at: 4
		put: (StMFullColumn 
				with: 0.0d
				with: yLength
				with: 0.0d).
	crfpointf at: 5 put: (crfpointf at: 1).
	^crfpointf</body>

<body package="CADSM-Geo" selector="rfpointsf">rfpointsf
	| rfpointsf |
	rfpointsf := StMArray new: 5.
	rfpointsf at: 1 put: (StMFullColumn zero: 3).
	rfpointsf at: 2
		put: (StMFullColumn 
				with: xLength
				with: 0.0d
				with: 0.0d).
	rfpointsf at: 3
		put: (StMFullColumn 
				with: xLength
				with: yLength
				with: 0.0d).
	rfpointsf at: 4
		put: (StMFullColumn 
				with: 0.0d
				with: yLength
				with: 0.0d).
	rfpointsf at: 5 put: (rfpointsf at: 1).
	^rfpointsf</body>

<body package="CADSM-Geo" selector="xLength">xLength
	^xLength</body>

<body package="CADSM-Geo" selector="xLength:">xLength: anObject
	xLength := anObject</body>

<body package="CADSM-Geo" selector="xLength:yLength:">xLength: argxLength yLength: argyLength 
	xLength := argxLength.
	yLength := argyLength</body>

<body package="CADSM-Geo" selector="yLength">yLength
	^yLength</body>

<body package="CADSM-Geo" selector="yLength:">yLength: anObject
	yLength := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRectangle</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="privateCalcBoundingBox">privateCalcBoundingBox
	aBoundingBox := CADSM.Misc.CADSMMiscBoundingBox origin: (StMFullColumn zero: 3)
				corner: (StMFullColumn 
						with: xLength
						with: yLength
						with: 0.0d)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRectangle class</class-id> <category>instancee creation</category>

<body package="CADSM-Geo" selector="xLength:yLength:">xLength: xLength yLength: yLength 
	^self new xLength: xLength yLength: yLength</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurfaceOfRevolution</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="aCurve">aCurve
	^aCurve</body>

<body package="CADSM-Geo" selector="condition_cLoopUse:within1:">condition_cLoopUse: cLoopUse within1: uvBound 
	| umin umax tol block uvShift |
	umin := uvBound umin.
	umax := uvBound umax.
	tol := 1.0d-6.
	self assert: [umax - umin &lt; (2.0d + tol)].
	block := 
			[:offset | 
			offset isZero 
				ifFalse: 
					[cLoopUse do: 
							[:aLoopUse | 
							aLoopUse ccuv 
								do: [:cuv | cuv do: [:uv | uv ifNotNil: [uv u: uv u - offset]]]]]].
	(umin equal: umin rounded tol: tol) 
		ifTrue: [block value: umin]
		ifFalse: 
			[(umax equal: umax rounded tol: tol) 
				ifTrue: [block value: umax - 1.0d]
				ifFalse: 
					[uvShift := self uvShiftToFituvBound: uvBound.
					uvShift ifNotNil: [CADSM.UI.STEP.SurfaceChangedException signalWith: self]]]</body>

<body package="CADSM-Geo" selector="condition_cLoopUse:within:">condition_cLoopUse: cLoopUse within: uvBound 
	| umin umax tol block uvShift |
	umin := uvBound umin.
	umax := uvBound umax.
	tol := 1.0d-6.
	self assert: [umax - umin &lt; (2.0d + tol)].
	block := 
			[:offset | 
			offset isZero 
				ifFalse: 
					[cLoopUse do: 
							[:aLoopUse | 
							aLoopUse ccuv 
								do: [:cuv | cuv do: [:uv | uv ifNotNil: [uv u: uv u - offset]]]]]].
	(umin equal: umin rounded tol: tol) 
		ifTrue: [block value: umin]
		ifFalse: 
			[(umax equal: umax rounded tol: tol) 
				ifTrue: [block value: umax - 1.0d]
				ifFalse: 
					[(umin &lt; tol negated or: [umax &gt; (1.0d + tol)]) 
						ifTrue: 
							[uvShift := self uvShiftToFituvBound: uvBound.
							uvShift ifNotNil: [CADSM.UI.STEP.SurfaceChangedException signalWith: self]]]]</body>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	aCurve magnifySelf: aDouble</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	aCurve reverseSelf</body>

<body package="CADSM-Geo" selector="rfpf_u:v:">rfpf_u: u v: v 
	| rCpC xyRadius z the x y |
	rCpC := aCurve rFpF_u: v.
	xyRadius := rCpC x.
	z := rCpC z.
	the := u * Double twoPi.
	x := xyRadius * the cos.
	y := xyRadius * the sin.
	^StMFullColumn 
		with: x
		with: y
		with: z</body>

<body package="CADSM-Geo" selector="smooth_cuv1:">smooth_cuv1: aaCurve 
	"
	Since the solid of revolution is periodic, u=0 is the same as u=integer.	
	"

	| cuv uvPrevious umin umax u uoffset tol |
	tol := 1.0d-6.
	cuv := aaCurve cuv.
	uvPrevious := (cuv at: 1) ifNil: [cuv at: 2].
	umin := umax := uvPrevious u.
	2 to: cuv size
		do: 
			[:i | 
			(cuv at: i) ifNotNil: 
					[:cuvi | 
					| du |
					du := cuvi u - uvPrevious u.
					cuvi u: cuvi u - du rounded.
					uvPrevious := cuvi.
					u := uvPrevious u.
					umin &lt; u ifFalse: [umin := u].
					umax &gt; u ifFalse: [umax := u]]].
	uoffset := umin &lt; (-1.0d + tol) 
				ifTrue: [(umin - tol) ceiling]
				ifFalse: [umax &gt; (1.0d + tol) ifTrue: [umax floor] ifFalse: [0.0d]].
	cuv do: [:cuvi | cuvi ifNotNil: [cuvi u: cuvi u - uoffset]]</body>

<body package="CADSM-Geo" selector="uvOfPoint:">uvOfPoint: rFpF 
	| rfpf x y z u v xyRadius |
	rfpf := aRefFrame rfpffromrFpF: rFpF.
	x := rfpf x.
	y := rfpf y.
	z := rfpf z.
	xyRadius := (x * x + (y * y)) sqrt.
	u := (Double 
				arcTan0to2piY: y
				overX: x
				ifUndefined: 0.0d) / Double twoPi.
	u := u \\ 1.0d.
	v := aCurve uOfPoint: (StMFullColumn 
						with: xyRadius
						with: 0.0d
						with: z).
	^u yd: v</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound1:">uvShiftToFituvBound1: uvBound 
	| umin umax |
	^(self uvBoundTol contains: uvBound) 
		ifTrue: [nil]
		ifFalse: 
			[umin := uvBound umin.
			umax := uvBound umax.
			(umin &lt; 0.0d or: [umax &gt; 1.0d]) 
				ifTrue: 
					[aRefFrame rotatez: umin * Double twoPi.
					StMFullColumn with: umin negated with: 0.0d]
				ifFalse: 
					[self assert: 
							[| tol |
							tol := 1.0d-9.
							0.0d - tol &lt;= uvBound vmin and: [uvBound vmax &lt;= (1.0d + tol)]].
					nil]]</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound2:">uvShiftToFituvBound2: uvBound 
	^(self uvBoundTol contains: uvBound) 
		ifTrue: [nil]
		ifFalse: 
			[(uvBound umin &lt; 0.0d or: [uvBound umax &gt; 1.0d]) 
				ifTrue: 
					[| uv umin |
					uv := self uv_gluv: uvBound minCorner.
					umin := uv first.
					aRefFrame rotatez: umin * Double twoPi.
					StMFullColumn with: umin negated with: 0.0d]]</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound:">uvShiftToFituvBound: gluvBound 
	"gluvBound is for glSurface NURBS."

	"ruvBound is uv in regular polar coordinate form."

	| ruvBound answer umin umax |
	ruvBound := self ruvBoundFrom: gluvBound.
	^(self uvBoundTol contains: ruvBound) 
		ifTrue: [nil]
		ifFalse: 
			[answer := StMFullColumn with: 0.0d with: 0.0d.
			umin := ruvBound umin.
			umax := ruvBound umax.
			umin &lt; 0.0d 
				ifTrue: 
					[umax &gt; 1.0d 
						ifTrue: 
							[umin abs &gt; (umax - 1.0d) 
								ifTrue: 
									[aRefFrame rotatez: umin * Double twoPi.
									answer at: 1 put: umin negated]
								ifFalse: 
									[aRefFrame rotatez: (umax - 1.0d) * Double twoPi.
									answer at: 1 put: (umax - 1.0d) negated]]
						ifFalse: 
							[aRefFrame rotatez: umin * Double twoPi.
							answer at: 1 put: umin negated]]
				ifFalse: 
					[umax &gt; 1.0d 
						ifTrue: 
							[aRefFrame rotatez: (umax - 1.0d) * Double twoPi.
							answer at: 1 put: (umax - 1.0d) negated]].
			answer]</body>

<body package="CADSM-Geo" selector="_aCurve:">_aCurve: aaCurve 
	aaCurve removeSup.
	super addRefFrame: aaCurve aRefFrame.
	aCurve := aaCurve.
	aaCurve aSup: self.
	^aaCurve</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurfaceOfRevolution</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="uv_gluv:">uv_gluv: gluv 
	| glu glv rFpF |
	glu := (gluv at: 1) \\ 1.0d.
	glv := gluv at: 2.
	rFpF := self glSurface rFpF_u: glu v: glv.
	^self uvOfPoint: rFpF</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurfaceOfRevolution</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="cEndSingularityOf:">cEndSingularityOf: aaCurve 
	^StMArray with: false with: false</body>

<body package="CADSM-Geo" selector="condition_cuv:">condition_cuv: aaCurve 
	"
	Since the solid of revolution is periodic, u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| umin umax cuv uvPrevious u tol offset |
	umin := StMMachineAccuracy OfLargestDouble.
	umax := StMMachineAccuracy OfLargestDouble negated.
	cuv := aaCurve cuv.
	uvPrevious := cuv at: 1.
	u := uvPrevious u.
	umin := umin min: u.
	umax := umax max: u.
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			uvPrevious := cuvi.
			u := uvPrevious u.
			umin := umin min: u.
			umax := umax max: u].
	tol := 1.0d-6.
	self assert: [umax - umin &lt; (1.0d + tol)].
	(umin - umin rounded) abs &lt; tol 
		ifTrue: 
			[offset := umin.
			cuv do: [:uv | uv ifNotNil: [uv u: uv u - offset]]]
		ifFalse: 
			[(umax - umax rounded) abs &lt; tol 
				ifTrue: 
					[offset := umax - 1.0d.
					cuv do: [:uv | uv ifNotNil: [uv u: uv u - offset]]]]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd1:">condition_cuv: cuv pre_uvEnd1: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| tol n uvPrevious |
	tol := 0.5d.
	n := cuv size.
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: [uvPrevious u: uvPrevious u \\ 1.0d]
		ifNotNil: 
			[(uvPrevious u - pre_uvend u) abs &gt; tol ifTrue: [uvPrevious u: pre_uvend u]].
	2 to: n
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			du abs &gt; tol 
				ifTrue: 
					[du positive 
						ifTrue: [cuvi u: cuvi u - 1.0d]
						ifFalse: [cuvi u: cuvi u + 1.0d]].
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd2:">condition_cuv: cuv pre_uvEnd2: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| tol n uvPrevious |
	tol := 0.5d.
	n := cuv size.
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: [uvPrevious u: uvPrevious u \\ 1.0d]
		ifNotNil: 
			[(uvPrevious u - pre_uvend u) abs &gt; tol ifTrue: [uvPrevious u: pre_uvend u]].
	2 to: n
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd3:">condition_cuv: cuv pre_uvEnd3: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| uvPrevious |
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: [uvPrevious u: uvPrevious u \\ 1.0d]
		ifNotNil: [uvPrevious u: pre_uvend u].
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd:">condition_cuv: cuv pre_uvEnd: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| uvPrevious |
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: [uvPrevious u: uvPrevious u \\ 1.0d]
		ifNotNil: 
			[uvPrevious u: pre_uvend u.
			uvPrevious v: pre_uvend v].
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:within:">condition_cuv: aaCurve within: aaBoundingRectangle 
	"
	Since the solid of revolution is periodic, u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| newBoundingRectangle cuv uvPrevious u |
	newBoundingRectangle := CADSMMiscBoundingRectangle new.
	cuv := aaCurve cuv.
	uvPrevious := cuv at: 1.
	aaBoundingRectangle isDefined 
		ifTrue: 
			[u := uvPrevious u.
			u := u - (u - aaBoundingRectangle umin) floor.
			uvPrevious u: u].
	newBoundingRectangle expandToBound: uvPrevious.
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			uvPrevious := cuvi.
			newBoundingRectangle expandToBound: uvPrevious].
	^newBoundingRectangle</body>

<body package="CADSM-Geo" selector="createNurbs">createNurbs
	^CADSMGeoNurbsSurface fromSolidOfRevolution: self</body>

<body package="CADSM-Geo" selector="rfpfNurbs">rfpfNurbs
	^CADSMGeoNurbsSurface fromSolidOfRevolution: self</body>

<body package="CADSM-Geo" selector="smooth_cuv:">smooth_cuv: aaCurve 
	"
	Since the solid of revolution is periodic, u=0 is the same as u=integer.	
	"

	| cuv uvPrevious umin umax u |
	cuv := aaCurve cuv.
	uvPrevious := (cuv at: 1) ifNil: [cuv at: 2].
	umin := umax := uvPrevious u.
	2 to: cuv size
		do: 
			[:i | 
			(cuv at: i) ifNotNil: 
					[:cuvi | 
					| du |
					du := cuvi u - uvPrevious u.
					cuvi u: cuvi u - du rounded.
					uvPrevious := cuvi.
					u := uvPrevious u.
					umin &lt; u ifFalse: [umin := u].
					umax &gt; u ifFalse: [umax := u]]]</body>

<body package="CADSM-Geo" selector="smooth_cuv:within1:">smooth_cuv: aaCurve within1: uvBound 
	| cuv uvPrevious u |
	cuv := aaCurve cuv.
	uvPrevious := cuv at: 1.
	u := uvPrevious u.
	u := u - (u - uvBound umin) floor.
	uvPrevious u: u.
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="smooth_cuv:within:">smooth_cuv: aaCurve within: uvBound 
	| cuv umin offset |
	self smooth_cuv: aaCurve.
	cuv := aaCurve cuv.
	(cuv allSatisfy: [:uv | uvBound contains: uv]) 
		ifFalse: 
			[umin := (cuv collect: [:uv | uv at: 1]) minValue.
			offset := (umin - uvBound umin) floor asDouble.
			offset isZero 
				ifFalse: 
					[1 to: cuv size
						do: 
							[:i | 
							| uv |
							uv := cuv at: i.
							uv u: uv u - offset]]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSurfaceOfRevolution</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	self _aCurve: aCurve copy</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphericalSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="radius">radius
	^aCurve _radius</body>

<body package="CADSM-Geo" selector="radius:">radius: aDouble 
	aCurve _radius: aDouble abs asDouble</body>

<body package="CADSM-Geo" selector="uvOfPoint:">uvOfPoint: rFpF 
	| uv tol |
	uv := super uvOfPoint: rFpF.
	tol := 1.0d-9.
	(uv v equal: 2.0d tol: tol) ifTrue: [uv v: 0.0d].
	^uv</body>

<body package="CADSM-Geo" selector="uv_gluv:">uv_gluv: gluv 
	"v = 0,1 is at singularity."

	| glu glv tol uv |
	glu := (gluv at: 1) \\ 1.0d.
	glv := gluv at: 2.
	tol := 1.0d-9.
	^(glv - glv rounded) abs &lt; tol 
		ifTrue: 
			[uv := super uv_gluv: (glu yd: 0.5d).
			uv u yd: glv]
		ifFalse: [super uv_gluv: gluv]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphericalSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="cEndSingularityOf:">cEndSingularityOf: aaCurve 
	| cuv tol n uv1 uvn v1 vn startSingularity endSingularity |
	cuv := aaCurve cuv.
	tol := 1.0d-6.
	n := cuv size.
	uv1 := (cuv at: 1) ifNil: 
					[cuv at: 1
						put: (StMFullColumn with: (cuv at: 2) u with: (cuv at: 2) v rounded asDouble)].
	uvn := (cuv at: n) ifNil: 
					[cuv at: n
						put: (StMFullColumn with: (cuv at: n - 1) u
								with: (cuv at: n - 1) v rounded asDouble)].
	v1 := uv1 v.
	vn := uvn v.
	startSingularity := false.
	endSingularity := false.
	((v1 equal: 0.0d tol: tol) or: [v1 equal: 1.0d tol: tol]) 
		ifTrue: 
			[uv1 u: (cuv at: 2) u.
			startSingularity := true].
	((vn equal: 0.0d tol: tol) or: [vn equal: 1.0d tol: tol]) 
		ifTrue: 
			[uvn u: (cuv at: n - 1) u.
			endSingularity := true].
	^StMArray with: startSingularity with: endSingularity</body>

<body package="CADSM-Geo" selector="condition_cuv:">condition_cuv: aaCurve 
	"
	Since the solid of revolution is periodic, u=0 is the same as u=integer.	
	Condition the series to have smooth u's.
	"

	| umin umax cuv uvPrevious u tol offset |
	umin := StMMachineAccuracy OfLargestDouble.
	umax := StMMachineAccuracy OfLargestDouble negated.
	cuv := aaCurve cuv.
	uvPrevious := (cuv at: 1) ifNil: [cuv at: 2].
	u := uvPrevious u.
	umin := umin min: u.
	umax := umax max: u.
	2 to: cuv size
		do: 
			[:i | 
			(cuv at: i) ifNotNil: 
					[:cuvi | 
					| du |
					du := cuvi u - uvPrevious u.
					cuvi u: cuvi u - du rounded.
					uvPrevious := cuvi.
					u := uvPrevious u.
					umin := umin min: u.
					umax := umax max: u]].
	tol := 1.0d-9.
	self assert: [umax - umin &lt; (1.0d + tol)].
	(umin - umin rounded) abs &lt; tol 
		ifTrue: 
			[offset := umin.
			cuv do: [:uv | uv ifNotNil: [uv u: uv u - offset]]]
		ifFalse: 
			[(umax - umax rounded) abs &lt; tol 
				ifTrue: 
					[offset := umax - 1.0d.
					cuv do: [:uv | uv ifNotNil: [uv u: uv u - offset]]]]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd1:">condition_cuv: cuv pre_uvEnd1: pre_uvend 
	| tol n uv1 uvn v1 vn new_pre_uvend |
	tol := 1.0d-6.
	n := cuv size.
	uv1 := cuv at: 1.
	uvn := cuv at: n.
	v1 := uv1 v.
	vn := uvn v.
	((v1 equal: 0.0d tol: tol) or: [v1 equal: 1.0d tol: tol]) 
		ifTrue: 
			[uv1 u: (cuv at: 2) u.
			"Discontinuity expected."
			new_pre_uvend := nil]
		ifFalse: 
			[((vn equal: 0.0d tol: tol) or: [vn equal: 1.0d tol: tol]) 
				ifTrue: [uvn u: (cuv at: n - 1) u].
			new_pre_uvend := pre_uvend].
	super condition_cuv: cuv pre_uvEnd: new_pre_uvend</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd2:">condition_cuv: cuv pre_uvEnd2: pre_uvend 
	| tol n uv1 uvn v1 vn |
	tol := 1.0d-6.
	n := cuv size.
	uv1 := cuv at: 1.
	uvn := cuv at: n.
	v1 := uv1 v.
	vn := uvn v.
	((v1 equal: 0.0d tol: tol) or: [v1 equal: 1.0d tol: tol]) 
		ifTrue: [uv1 u: (cuv at: 2) u]
		ifFalse: 
			[((vn equal: 0.0d tol: tol) or: [vn equal: 1.0d tol: tol]) 
				ifTrue: [uvn u: (cuv at: n - 1) u]].
	super condition_cuv: cuv pre_uvEnd: pre_uvend</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd:">condition_cuv: cuv pre_uvEnd: pre_uvend 
	| tol n uv1 uvn v1 vn new_pre_uvend |
	tol := 1.0d-6.
	n := cuv size.
	uv1 := cuv at: 1.
	uvn := cuv at: n.
	v1 := uv1 v.
	vn := uvn v.
	((v1 equal: 0.0d tol: tol) or: [v1 equal: 1.0d tol: tol]) 
		ifTrue: 
			[uv1 u: (cuv at: 2) u.
			"Discontinuity expected."
			new_pre_uvend := nil]
		ifFalse: 
			[((vn equal: 0.0d tol: tol) or: [vn equal: 1.0d tol: tol]) 
				ifTrue: [uvn u: (cuv at: n - 1) u].
			new_pre_uvend := pre_uvend].
	super condition_cuv: cuv pre_uvEnd: new_pre_uvend</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc1:">uvCurveOfEllipticArc1: aEllipticArc 
	^(self isMeridian: aEllipticArc) 
		ifTrue: 
			[| cnPoint cnPointOn_uv |
			cnPoint := aEllipticArc nPoint: 4.
			cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
			(CADSMGeoLine new)
				isSpatial: false;
				cuv: cnPointOn_uv;
				yourself]
		ifFalse: [self uvCurveOfCurve: aEllipticArc]</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:">uvCurveOfEllipticArc: aEllipticArc 
	^(self isMeridian: aEllipticArc) 
		ifTrue: 
			[| glSurface cnPoint cnPointOn_uv |
			glSurface := self glSurface.
			cnPoint := aEllipticArc nPoint: 4.
			cnPointOn_uv := cnPoint collect: 
							[:aPointXYZ | 
							| uvGuess |
							uvGuess := self uvOfPoint: aPointXYZ.
							glSurface uvOfPoint: aPointXYZ uvGuess: uvGuess].
			(CADSMGeoLine new)
				isSpatial: false;
				cuv: cnPointOn_uv;
				yourself]
		ifFalse: [self uvCurveOfCurve: aEllipticArc]</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:preCurve:">uvCurveOfEllipticArc: aEllipticArc preCurve: preCurve 
	^(self isMeridian: aEllipticArc) 
		ifTrue: 
			[| cnPoint cnPointOn_uv pre_uvEnd uvStart uvEnd uvLine |
			cnPoint := aEllipticArc nPoint: 4.
			cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
			pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
			self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
			uvStart := cnPointOn_uv first.
			uvEnd := cnPointOn_uv last.
			uvLine := CADSMGeoLine new.
			uvLine
				isSpatial: false;
				uvStart: uvStart;
				uvEnd: uvEnd;
				dsdt: 1 / (uvEnd - uvStart) length;
				privateCalcBoundingBox;
				yourself]
		ifFalse: [self uvCurveOfCurve: aEllipticArc preCurve: preCurve]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphericalSurface</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs1:">condition_cglTrimNurbs1: cglTrimNurbs 
	| tol uvStart uvEnd aStream uvNext uvStarti v aPoint bPoint cPoint dPoint |
	tol := 1.0d-6.
	uvStart := cglTrimNurbs first uvStart.
	uvEnd := cglTrimNurbs last uvEnd.
	^(uvStart - uvEnd) length &lt; tol 
		ifTrue: 
			[aStream := (cglTrimNurbs species new: cglTrimNurbs size) writeStream.
			uvNext := uvStart.
			cglTrimNurbs do: 
					[:glTrimNurbs | 
					uvStarti := glTrimNurbs uvStart.
					(uvNext - uvStarti) length &lt; tol 
						ifFalse: 
							[self name: #debug.
							aStream nextPut: (CADSMGeoNurbsCurve fromStart: uvNext copy toEnd: uvStarti copy)].
					aStream nextPut: glTrimNurbs.
					uvNext := glTrimNurbs uvEnd].
			(uvNext - uvStart) length &lt; tol 
				ifFalse: 
					[self name: #debug.
					aStream nextPut: (CADSMGeoNurbsCurve fromStart: uvNext copy toEnd: uvStart copy)].
			aStream contents]
		ifFalse: 
			[((uvStart v equal: 0.0d tol: tol) or: [uvStart v equal: 1.0d tol: tol]) 
				ifTrue: 
					[self name: #debug.
					cglTrimNurbs
						addLast: (CADSMGeoNurbsCurve fromStart: uvEnd copy toEnd: uvStart copy);
						yourself]
				ifFalse: 
					[self name: #debug.
					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.
					cglTrimNurbs
						addLast: (CADSMGeoNurbsCurve fromStart: aPoint copy toEnd: bPoint copy);
						addLast: (CADSMGeoNurbsCurve fromStart: bPoint copy toEnd: cPoint copy);
						addLast: (CADSMGeoNurbsCurve fromStart: cPoint copy toEnd: dPoint copy);
						yourself]]</body>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs:">condition_cglTrimNurbs: cglTrimNurbs 
	| tol uvStart uvEnd aStream uvNext uvStarti v aPoint bPoint cPoint dPoint |
	tol := 1.0d-4.
	uvStart := cglTrimNurbs first uvStart.
	uvEnd := cglTrimNurbs last uvEnd.
	^(uvStart - uvEnd) length &lt; tol 
		ifTrue: 
			[aStream := (cglTrimNurbs species new: cglTrimNurbs size) writeStream.
			uvNext := uvStart.
			cglTrimNurbs do: 
					[:glTrimNurbs | 
					uvStarti := glTrimNurbs uvStart.
					(uvNext - uvStarti) length &lt; tol 
						ifFalse: 
							[self name: #debug.
							aStream nextPut: (CADSMGeoNurbsCurve 
										fromStart: uvNext copy
										toEnd: uvStarti copy
										isSpatial: false)].
					aStream nextPut: glTrimNurbs.
					uvNext := glTrimNurbs uvEnd].
			(uvNext - uvStart) length &lt; tol 
				ifFalse: 
					[self name: #debug.
					aStream nextPut: (CADSMGeoNurbsCurve 
								fromStart: uvNext copy
								toEnd: uvStart copy
								isSpatial: false)].
			aStream contents]
		ifFalse: 
			[((uvStart v equal: 0.0d tol: tol) or: [uvStart v equal: 1.0d tol: tol]) 
				ifTrue: 
					[self name: #debug.
					cglTrimNurbs
						addLast: (CADSMGeoNurbsCurve 
									fromStart: uvEnd copy
									toEnd: uvStart copy
									isSpatial: false);
						yourself]
				ifFalse: 
					[self name: #debug.
					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.
					cglTrimNurbs
						addLast: (CADSMGeoNurbsCurve 
									fromStart: aPoint copy
									toEnd: bPoint copy
									isSpatial: false);
						addLast: (CADSMGeoNurbsCurve 
									fromStart: bPoint copy
									toEnd: cPoint copy
									isSpatial: false);
						addLast: (CADSMGeoNurbsCurve 
									fromStart: cPoint copy
									toEnd: dPoint copy
									isSpatial: false);
						yourself]]</body>

<body package="CADSM-Geo" selector="isMeridian:">isMeridian: aEllipticArc 
	| tol |
	tol := 1.0d-6.
	^(self radius equal: aEllipticArc _radius tol: tol) and: 
			[((aRefFrame aAFf column: 3) dot: (aEllipticArc aRefFrame aAFf column: 3)) 
				equal: 0.0d
				tol: tol]</body>

<body package="CADSM-Geo" selector="reverseSelf">reverseSelf
	aCurve aRefFrame rotatey: Double pi</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSphericalSurface</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	"The semi circular arc starts from the south pole to the north pole in the xz plane."

	| aEllipticArc |
	super initialize.
	aEllipticArc := (CADSM.Geo.CADSMGeoEllipticArc new)
				_radius: 0.0d;
				theStart: 0.0d;
				theEnd: Double pi;
				yourself.
	aEllipticArc aRefFrame rotatex: Double pi / 2.0d.
	aEllipticArc aRefFrame rotatez: Double pi / 2.0d negated.
	self _aCurve: aEllipticArc</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoToroidalSurface</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	"Circle must in xz plane."

	| aCircle |
	super initialize.
	aCircle := (CADSM.Geo.CADSMGeoCircle new)
				_radius: 0.0d;
				yourself.
	aCircle aRefFrame rotatex: Double pi / 2.0d.
	self _aCurve: aCircle</body>

<body package="CADSM-Geo" selector="initialize1">initialize1
	"Circle must in xz plane."

	| aCircle |
	super initialize.
	aCircle := (CADSM.Geo.CADSMGeoCircle new)
				_radius: 0.0d;
				yourself.
	aCircle aRefFrame rotatex: Double pi / 2.0d.
	self _aCurve: aCircle</body>

<body package="CADSM-Geo" selector="initialize2">initialize2
	"Circle must in xz plane."

	| aCircle |
	super initialize.
	aCircle := (CADSM.Geo.CADSMGeoCircle new)
				_radius: 0.0d;
				yourself.
	aCircle aRefFrame rotatex: Double pi / 2.0d.
	aCircle aRefFrame rotatez: Double pi / 2.0d negated.
	self _aCurve: aCircle</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoToroidalSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="majorRadius">majorRadius
	^aCurve aRefFrame rFfF x</body>

<body package="CADSM-Geo" selector="majorRadius:">majorRadius: aDouble 
	^aCurve aRefFrame rFfF x: aDouble asDouble</body>

<body package="CADSM-Geo" selector="minorRadius">minorRadius
	^aCurve _radius</body>

<body package="CADSM-Geo" selector="minorRadius:">minorRadius: aDouble 
	^aCurve _radius: aDouble asDouble</body>

<body package="CADSM-Geo" selector="uv_gluv:">uv_gluv: gluv 
	| glu glv rFpF |
	glu := (gluv at: 1) \\ 1.0d.
	glv := (gluv at: 2) \\ 1.0d.
	rFpF := self glSurface rFpF_u: glu v: glv.
	^self uvOfPoint: rFpF</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoToroidalSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="condition_cLoopUse:within:">condition_cLoopUse: cLoopUse within: uvBound 
	| vmin vmax tol block uvShift |
	vmin := uvBound vmin.
	vmax := uvBound vmax.
	tol := 1.0d-6.
	self assert: [vmax - vmin &lt; (2.0d + tol)].
	block := 
			[:offset | 
			offset isZero 
				ifFalse: 
					[cLoopUse do: 
							[:aLoopUse | 
							aLoopUse ccuv 
								do: [:cuv | cuv do: [:uv | uv ifNotNil: [uv v: uv v - offset]]]]]].
	(vmin equal: vmin rounded tol: tol) 
		ifTrue: [block value: vmin]
		ifFalse: 
			[(vmax equal: vmax rounded tol: tol) 
				ifTrue: [block value: vmax - 1.0d]
				ifFalse: 
					[uvShift := self uvShiftToFituvBound: uvBound.
					uvShift ifNotNil: [CADSM.UI.STEP.SurfaceChangedException signalWith: self]]].
	super condition_cLoopUse: cLoopUse within: uvBound</body>

<body package="CADSM-Geo" selector="smooth_cuv:within:">smooth_cuv: aaCurve within: uvBound 
	| cuv uvPrevious u v |
	cuv := aaCurve cuv.
	(cuv allSatisfy: [:uv | uvBound contains: uv]) 
		ifFalse: 
			[uvPrevious := cuv at: 1.
			u := uvPrevious u.
			u := u - (u - uvBound umin) floor.
			uvPrevious u: u.
			v := uvPrevious v.
			v := v - (v - uvBound vmin) floor.
			uvPrevious v: v.
			2 to: cuv size
				do: 
					[:i | 
					| cuvi du dv |
					cuvi := cuv at: i.
					du := cuvi u - uvPrevious u.
					cuvi u: cuvi u - du rounded.
					dv := cuvi v - uvPrevious v.
					cuvi v: cuvi v - dv rounded.
					uvPrevious := cuvi]]</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc1:">uvCurveOfEllipticArc1: aEllipticArc 
	| cnPoint cnPointOn_uv |
	cnPoint := aEllipticArc nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:">uvCurveOfEllipticArc: aEllipticArc 
	| glSurface cnPoint cnPointOn_uv |
	glSurface := self glSurface.
	cnPoint := aEllipticArc nPoint: 4.
	cnPointOn_uv := cnPoint collect: 
					[:aPointXYZ | 
					| uvGuess |
					uvGuess := self uvOfPoint: aPointXYZ.
					glSurface uvOfPoint: aPointXYZ uvGuess: uvGuess].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:preCurve:">uvCurveOfEllipticArc: aEllipticArc preCurve: preCurve 
	| cnPoint cnPointOn_uv pre_uvEnd uvStart uvEnd uvLine |
	cnPoint := aEllipticArc nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	uvStart := cnPointOn_uv first.
	uvEnd := cnPointOn_uv last.
	uvLine := CADSMGeoLine new.
	uvLine
		isSpatial: false;
		uvStart: uvStart;
		uvEnd: uvEnd;
		dsdt: 1 / (uvEnd - uvStart) length;
		privateCalcBoundingBox.
	^uvLine</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound1:">uvShiftToFituvBound1: uvBound 
	^(self uvBoundTol contains: uvBound) 
		ifTrue: [nil]
		ifFalse: 
			[| answer umin umax vmin vmax |
			answer := StMFullColumn with: 0.0d with: 0.0d.
			umin := uvBound umin.
			umax := uvBound umax.
			(umin &lt; 0.0d or: [umax &gt; 1.0d]) 
				ifTrue: 
					[aRefFrame rotatez: umin * Double twoPi.
					answer at: 1 put: umin negated].
			vmin := uvBound vmin.
			vmax := uvBound vmax.
			(vmin &lt; 0.0d or: [vmax &gt; 1.0d]) 
				ifTrue: 
					[aCurve aRefFrame rotatez: vmin * Double twoPi.
					answer at: 2 put: vmin negated].
			answer]</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound2:">uvShiftToFituvBound2: uvBound 
	"uvBound is for glSurface."

	| answer uv umin umax vmin vmax |
	^(self uvBoundTol contains: uvBound) 
		ifTrue: [nil]
		ifFalse: 
			[answer := StMFullColumn with: 0.0d with: 0.0d.
			uv := self uv_gluv: uvBound minCorner.
			umin := uvBound umin.
			umax := uvBound umax.
			(umin &lt; 0.0d or: [umax &gt; 1.0d]) 
				ifTrue: 
					[umin := uv first.
					aRefFrame rotatez: umin * Double twoPi.
					answer at: 1 put: umin negated].
			vmin := uvBound vmin.
			vmax := uvBound vmax.
			(vmin &lt; 0.0d or: [vmax &gt; 1.0d]) 
				ifTrue: 
					[vmin := uv last.
					aCurve aRefFrame rotatez: vmin * Double twoPi.
					answer at: 2 put: vmin negated].
			answer]</body>

<body package="CADSM-Geo" selector="uvShiftToFituvBound:">uvShiftToFituvBound: gluvBound 
	"gluvBound is for glSurface NURBS."

	"ruvBound is uv in regular polar coordinate form."

	| ruvBound answer umin umax vmin vmax |
	ruvBound := self ruvBoundFrom: gluvBound.
	^(self uvBoundTol contains: ruvBound) 
		ifTrue: [nil]
		ifFalse: 
			[answer := StMFullColumn with: 0.0d with: 0.0d.
			umin := ruvBound umin.
			umax := ruvBound umax.
			umin &lt; 0.0d 
				ifTrue: 
					[umax &gt; 1.0d 
						ifTrue: 
							[umin abs &gt; (umax - 1.0d) 
								ifTrue: 
									[aRefFrame rotatez: umin * Double twoPi.
									answer at: 1 put: umin negated]
								ifFalse: 
									[aRefFrame rotatez: (umax - 1.0d) * Double twoPi.
									answer at: 1 put: (umax - 1.0d) negated]]
						ifFalse: 
							[aRefFrame rotatez: umin * Double twoPi.
							answer at: 1 put: umin negated]]
				ifFalse: 
					[umax &gt; 1.0d 
						ifTrue: 
							[aRefFrame rotatez: (umax - 1.0d) * Double twoPi.
							answer at: 1 put: (umax - 1.0d) negated]].
			vmin := ruvBound vmin.
			vmax := ruvBound vmax.
			vmin &lt; 0.0d 
				ifTrue: 
					[vmax &gt; 1.0d 
						ifTrue: 
							[vmin abs &gt; (vmax - 1.0d) 
								ifTrue: 
									[aCurve aRefFrame rotatez: vmin * Double twoPi.
									answer at: 2 put: vmin negated]
								ifFalse: 
									[aCurve aRefFrame rotatez: (vmax - 1.0d) * Double twoPi.
									answer at: 2 put: (vmax - 1.0d) negated]]
						ifFalse: 
							[aCurve aRefFrame rotatez: vmin * Double twoPi.
							answer at: 2 put: vmin negated]]
				ifFalse: 
					[vmax &gt; 1.0d 
						ifTrue: 
							[aCurve aRefFrame rotatez: (vmax - 1.0d) * Double twoPi.
							answer at: 2 put: (vmax - 1.0d) negated]].
			answer]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoToroidalSurface</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="condition_cuv:">condition_cuv: aaCurve 
	"
	Since the torus is periodic in v, v=0 is the same as v=integer.	
	Condition the series to have smooth v's.
	"

	| vmin vmax cuv uvPrevious v tol offset |
	vmin := StMMachineAccuracy OfLargestDouble.
	vmax := StMMachineAccuracy OfLargestDouble negated.
	cuv := aaCurve cuv.
	uvPrevious := cuv at: 1.
	v := uvPrevious v.
	vmin := vmin min: v.
	vmax := vmax max: v.
	2 to: cuv size
		do: 
			[:i | 
			| cuvi dv |
			cuvi := cuv at: i.
			dv := cuvi v - uvPrevious v.
			cuvi v: cuvi v - dv rounded.
			uvPrevious := cuvi.
			v := uvPrevious v.
			vmin := vmin min: v.
			vmax := vmax max: v].
	tol := 1.0d-9.
	self assert: [vmax - vmin &lt; (1.0d + tol)].
	(vmin - vmin rounded) abs &lt; tol 
		ifTrue: 
			[offset := vmin.
			cuv do: [:uv | uv ifNotNil: [uv v: uv v - offset]]]
		ifFalse: 
			[(vmax - vmax rounded) abs &lt; tol 
				ifTrue: 
					[offset := vmax - 1.0d.
					cuv do: [:uv | uv ifNotNil: [uv v: uv v - offset]]]].
	^super condition_cuv: aaCurve</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd1:">condition_cuv: cuv pre_uvEnd1: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's and v's.
	"

	| tol n uvPrevious |
	tol := 0.5d.
	n := cuv size.
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: 
			[uvPrevious u: uvPrevious u \\ 1.0d.
			uvPrevious v: uvPrevious v \\ 1.0d]
		ifNotNil: 
			[(uvPrevious u - pre_uvend u) abs &gt; tol ifTrue: [uvPrevious u: pre_uvend u].
			(uvPrevious v - pre_uvend v) abs &gt; tol ifTrue: [uvPrevious v: pre_uvend v]].
	2 to: n
		do: 
			[:i | 
			| cuvi du dv |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			du abs &gt; tol 
				ifTrue: 
					[du positive 
						ifTrue: [cuvi u: cuvi u - 1.0d]
						ifFalse: [cuvi u: cuvi u + 1.0d]].
			dv := cuvi v - uvPrevious v.
			dv abs &gt; tol 
				ifTrue: 
					[dv positive 
						ifTrue: [cuvi v: cuvi v - 1.0d]
						ifFalse: [cuvi v: cuvi v + 1.0d]].
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd2:">condition_cuv: cuv pre_uvEnd2: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's and v's.
	"

	| uvPrevious |
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: 
			[uvPrevious u: uvPrevious u \\ 1.0d.
			uvPrevious v: uvPrevious v \\ 1.0d]
		ifNotNil: 
			[uvPrevious u: pre_uvend u.
			uvPrevious v: pre_uvend v].
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du dv |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			dv := cuvi v - uvPrevious v.
			cuvi v: cuvi v - dv rounded.
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:pre_uvEnd:">condition_cuv: cuv pre_uvEnd: pre_uvend 
	"
	Since the cylinder is periodic u=0 is the same as u=integer.	
	Condition the series to have smooth u's and v's.
	"

	| uvPrevious |
	uvPrevious := cuv at: 1.
	pre_uvend ifNil: 
			[uvPrevious u: uvPrevious u \\ 1.0d.
			uvPrevious v: uvPrevious v \\ 1.0d]
		ifNotNil: 
			[uvPrevious u: pre_uvend u.
			uvPrevious v: pre_uvend v].
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du dv |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			dv := cuvi v - uvPrevious v.
			cuvi v: cuvi v - dv rounded.
			uvPrevious := cuvi]</body>

<body package="CADSM-Geo" selector="condition_cuv:within:">condition_cuv: aaCurve within: aaBoundingRectangle 
	"
	Since the toroidal surface is periodic, v=0 is the same as v=integer.	
	Condition the series to have smooth v's.
	"

	| newBoundingRectangle cuv uvPrevious u v |
	newBoundingRectangle := CADSMMiscBoundingRectangle new.
	cuv := aaCurve cuv.
	uvPrevious := cuv at: 1.
	aaBoundingRectangle isDefined 
		ifTrue: 
			[u := uvPrevious u.
			u := u - (u - aaBoundingRectangle umin) floor.
			uvPrevious u: u.
			v := uvPrevious v.
			v := v - (v - aaBoundingRectangle vmin) floor.
			uvPrevious v: v].
	newBoundingRectangle expandToBound: uvPrevious.
	2 to: cuv size
		do: 
			[:i | 
			| cuvi du dv |
			cuvi := cuv at: i.
			du := cuvi u - uvPrevious u.
			cuvi u: cuvi u - du rounded.
			dv := cuvi v - uvPrevious v.
			cuvi v: cuvi v - dv rounded.
			uvPrevious := cuvi.
			newBoundingRectangle expandToBound: uvPrevious].
	^newBoundingRectangle</body>

<body package="CADSM-Geo" selector="smooth_cuv:">smooth_cuv: aaCurve 
	"
	Since the torus is periodic in v, v=0 is the same as v=integer.	
	"

	| cuv uvPrevious |
	cuv := aaCurve cuv.
	uvPrevious := cuv at: 1.
	2 to: cuv size
		do: 
			[:i | 
			| cuvi dv |
			cuvi := cuv at: i.
			dv := cuvi v - uvPrevious v.
			cuvi v: cuvi v - dv rounded.
			uvPrevious := cuvi].
	^super smooth_cuv: aaCurve</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCylindricalSurface</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	| aLine |
	super initialize.
	aLine := (CADSM.Geo.CADSMGeoLine new)
				rfstartf: (StMFullColumn zero: 3);
				rfendf: (StMFullColumn zero: 3);
				yourself.
	self _aCurve: aLine</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoCylindricalSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc1:">uvCurveOfEllipticArc1: aEllipticArc 
	| cnPoint cnPointOn_uv |
	cnPoint := aEllipticArc nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:">uvCurveOfEllipticArc: aEllipticArc 
	"uv of cylindrical surface is not the same as the uv of Nurbs cylinder."

	| glSurface cnPoint cnPointOn_uv |
	glSurface := self glSurface.
	cnPoint := aEllipticArc nPoint: 4.
	cnPointOn_uv := cnPoint collect: 
					[:aPointXYZ | 
					| uvGuess |
					uvGuess := self uvOfPoint: aPointXYZ.
					glSurface uvOfPoint: aPointXYZ uvGuess: uvGuess].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfEllipticArc:preCurve:">uvCurveOfEllipticArc: aEllipticArc preCurve: preCurve 
	| cnPoint cnPointOn_uv pre_uvEnd uvStart uvEnd uvLine |
	cnPoint := aEllipticArc nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	uvStart := cnPointOn_uv first.
	uvEnd := cnPointOn_uv last.
	uvLine := CADSMGeoLine new.
	uvLine
		isSpatial: false;
		uvStart: uvStart;
		uvEnd: uvEnd;
		dsdt: 1 / (uvEnd - uvStart) length;
		privateCalcBoundingBox.
	^uvLine</body>

<body package="CADSM-Geo" selector="uvCurveOfLine1:">uvCurveOfLine1: aLine 
	| cnPoint cnPointOn_uv |
	cnPoint := aLine nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:">uvCurveOfLine: aLine 
	"uv of cylindrical surface is not the same as the uv of Nurbs cylinder."

	| glSurface cnPoint cnPointOn_uv |
	glSurface := self glSurface.
	cnPoint := aLine nPoint: 4.
	cnPointOn_uv := cnPoint collect: 
					[:aPointXYZ | 
					| uvGuess |
					uvGuess := self uvOfPoint: aPointXYZ.
					glSurface uvOfPoint: aPointXYZ uvGuess: uvGuess].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:preCurve:">uvCurveOfLine: aLine preCurve: preCurve 
	| cnPoint cnPointOn_uv pre_uvEnd uvStart uvEnd uvLine |
	cnPoint := aLine nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	uvStart := cnPointOn_uv first.
	uvEnd := cnPointOn_uv last.
	uvLine := CADSMGeoLine new.
	uvLine
		isSpatial: false;
		uvStart: uvStart;
		uvEnd: uvEnd;
		dsdt: 1 / (uvEnd - uvStart) length;
		privateCalcBoundingBox.
	^uvLine</body>

<body package="CADSM-Geo" selector="_radius">_radius
	^aCurve rfstartf x</body>

<body package="CADSM-Geo" selector="_radius:">_radius: radius 
	aCurve rfstartf x: radius asDouble.
	aCurve rfendf x: radius asDouble</body>

<body package="CADSM-Geo" selector="_zend:">_zend: zend 
	aCurve rfendf z: zend</body>

<body package="CADSM-Geo" selector="_zstart:">_zstart: zstart 
	aCurve rfstartf z: zstart</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRefGeo</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="addMarker:">addMarker: aMarker 
	(self 
		is: aMarker
		kindOf: CADSMGeoMarker
		validFor: cMarker) 
			ifTrue: 
				[aMarker removeSup.
				super addRefFrame: aMarker aRefFrame.
				cMarker add: aMarker.
				aMarker aSup: self.
				self calcBoundingBox].
	^aMarker</body>

<body package="CADSM-Geo" selector="addMarkers:">addMarkers: array 
	array do: [:marker | self addMarker: marker]</body>

<body package="CADSM-Geo" selector="findMarkerNamed:">findMarkerNamed: nameComponents 
	| cShortenedNameComponent answer |
	self name = (nameComponents at: 1) ifFalse: [^nil].
	cShortenedNameComponent := nameComponents copyFrom: 2
				to: nameComponents size.
	cMarker do: 
			[:aMarker | 
			(answer := aMarker findMarkerNamed: cShortenedNameComponent) 
				ifNotNil: [^answer]].
	^answer</body>

<body package="CADSM-Geo" selector="findMarkerNamedOld:">findMarkerNamedOld: nameComponents 
	| answer |
	cMarker do: 
			[:aMarker | 
			(answer := aMarker findMarkerNamedOld: nameComponents) ifNotNil: [^answer]].
	^answer</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	cMarker do: [:item | item storeInputState]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRefGeo</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	cMarker := CADSM.Misc.CADSMMiscOrderedSet new</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRefGeo</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="cItemWithBoundingBox">cItemWithBoundingBox
	^(OrderedCollection new: cMarker size)
		addAll: cMarker;
		yourself</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRefCurve</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="addCurveMarkers:">addCurveMarkers: array 
	array do: [:marker | self addMarker: marker]</body>

<body package="CADSM-Geo" selector="rfCurvef">rfCurvef
	^rfEqnf</body>

<body package="CADSM-Geo" selector="rfCurvef:">rfCurvef: anObject
	rfEqnf := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRefCurve</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| aMbDRefCurve |
	aMbDRefCurve := CADSMMbDRefCurve new.
	aMbDRefCurve name: self name.
	aMbDRefCurve rfEqnf: rfEqnf / self aMbDUnits length.
	aSup mbdObject addRefGeo: aMbDRefCurve.
	self mbdObject: aMbDRefCurve</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoRefSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="rfSurfacef">rfSurfacef
	^rfEqnf</body>

<body package="CADSM-Geo" selector="rfSurfacef:">rfSurfacef: anObject 
	rfEqnf := anObject</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConstantVelocityJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDConstantVelocityJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'ConstantVelocityJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelLighting</class-id> <category>lighting</category>

<body package="CADSM-Geo" selector="lightingOn:">lightingOn: aRenderingContext 
	| index |
	index := aRenderingContext getLightIndex.
	aRenderingContext 
		lightIndex: index
		position: nil
		direction: self direction
		cutoffAngle: nil
		color: self color
		alpha: self alpha.
	aRenderingContext enableLightIndex: index.
	aRenderingContext enableLighting</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelLighting</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aDialog">aDialog
	^StCAD.CADParallelLightingDialog openOn: self</body>

<body package="CADSM-Geo" selector="direction">direction
	^aRefFrame aAFf column: 3</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoParallelLighting class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="color:direction:">color: aColor direction: array 
	| answer zDir xDir aA |
	answer := self new.
	answer color: aColor.
	zDir := StMFullColumn 
				with: (array at: 1) asDouble
				with: (array at: 2) asDouble
				with: (array at: 3) asDouble.
	zDir normalizeSelf.
	xDir := StMFullColumn 
				with: 1.0d
				with: 0.0d
				with: 0.0d.
	(xDir cross: zDir) length &lt; 1.0d-1 
		ifTrue: 
			[xDir := StMFullColumn 
						with: 0.0d
						with: 1.0d
						with: 0.0d].
	aA := StMFullMatrix rotationMatrixFromzDir: zDir xDir: xDir.
	answer aRefFrame aAFf: aA.
	^answer</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTime</class-id> <category>MbD</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| aMbDTime aGeoTime |
	aMbDTime := self aMediator aMbDUniverse aMbDTime.
	x == aMbDTime 
		ifFalse: 
			[aGeoTime := aMbDTime * self aMbDUnits time.
			self x: aMbDTime expression: aGeoTime simplified]</body>

<body package="CADSM-Geo" selector="deleteMbD">deleteMbD
	x := nil.
	expression := nil</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoTime</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aMbDUnits">aMbDUnits
	^container ifNotNil: [container aMbDUnits]</body>

<body package="CADSM-Geo" selector="aMediator">aMediator
	^container ifNotNil: [container aMediator]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="cEndSingularityOf:">cEndSingularityOf: aaCurve 
	| cuv tol n startSingularity endSingularity |
	cuv := aaCurve cuv.
	tol := 1.0d-6.
	n := cuv size.
	startSingularity := false.
	endSingularity := false.
	(cuv at: 1) ifNil: 
			[cuv at: 1
				put: (StMFullColumn with: (cuv at: 2) u with: (cuv at: 2) v rounded asDouble).
			startSingularity := true]
		ifNotNil: 
			[:uv1 | 
			(self isSingular_v: uv1 v tol: tol) 
				ifTrue: 
					[uv1 u: (cuv at: 2) u.
					startSingularity := true]].
	(cuv at: n) ifNil: 
			[cuv at: n
				put: (StMFullColumn with: (cuv at: n - 1) u
						with: (cuv at: n - 1) v rounded asDouble).
			endSingularity := true]
		ifNotNil: 
			[:uvn | 
			(self isSingular_v: uvn v tol: tol) 
				ifTrue: 
					[uvn u: (cuv at: n - 1) u.
					endSingularity := true]].
	^StMArray with: startSingularity with: endSingularity</body>

<body package="CADSM-Geo" selector="radius">radius
	^radius</body>

<body package="CADSM-Geo" selector="radius:">radius: aDouble 
	radius := aDouble abs asDouble</body>

<body package="CADSM-Geo" selector="semi_angle">semi_angle
	^semi_angle</body>

<body package="CADSM-Geo" selector="semi_angle:">semi_angle: aDouble 
	semi_angle := aDouble abs asDouble</body>

<body package="CADSM-Geo" selector="_zend:">_zend: zend 
	| rfendf |
	rfendf := aCurve rfendf.
	rfendf z: zend.
	rfendf x: radius + (zend * semi_angle tan)</body>

<body package="CADSM-Geo" selector="_zstart:">_zstart: zstart 
	| rfstartf |
	rfstartf := aCurve rfstartf.
	rfstartf z: zstart.
	rfstartf x: radius + (zstart * semi_angle tan)</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id> <category>As yet unclassified</category>

<body package="CADSM-Geo" selector="isEndSingular_tol:">isEndSingular_tol: tol 
	^aCurve rfendf x &lt; (tol * aBoundingBox diagonal_length)</body>

<body package="CADSM-Geo" selector="isSingular_v:tol:">isSingular_v: v tol: tol 
	"If cone has an apex, singularity is when v is 0 or 1."

	^(v equal: 0.0d tol: tol) 
		ifTrue: [self isStartSingular_tol: tol]
		ifFalse: 
			[(v equal: 1.0d tol: tol) 
				ifTrue: [self isEndSingular_tol: tol]
				ifFalse: [false]]</body>

<body package="CADSM-Geo" selector="isStartSingular_tol:">isStartSingular_tol: tol 
	^aCurve rfstartf x &lt; (tol * aBoundingBox diagonal_length)</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:">uvCurveOfLine: aLine 
	| glSurface cnPoint cnPointOn_uv |
	glSurface := self glSurface.
	cnPoint := aLine nPoint: 4.
	cnPointOn_uv := cnPoint collect: 
					[:aPointXYZ | 
					| uvGuess |
					uvGuess := self uvOfPoint: aPointXYZ.
					glSurface uvOfPoint: aPointXYZ uvGuess: uvGuess].
	^(CADSMGeoLine new)
		isSpatial: false;
		cuv: cnPointOn_uv;
		yourself</body>

<body package="CADSM-Geo" selector="uvCurveOfLine:preCurve:">uvCurveOfLine: aLine preCurve: preCurve 
	| cnPoint cnPointOn_uv pre_uvEnd uvStart uvEnd uvLine |
	cnPoint := aLine nPoint: 4.
	cnPointOn_uv := cnPoint collect: [:aPointXYZ | self uvOfPoint: aPointXYZ].
	pre_uvEnd := preCurve ifNotNil: [preCurve uvEnd].
	self condition_cuv: cnPointOn_uv pre_uvEnd: pre_uvEnd.
	uvStart := cnPointOn_uv first.
	uvEnd := cnPointOn_uv last.
	uvLine := CADSMGeoLine new.
	uvLine
		isSpatial: false;
		uvStart: uvStart;
		uvEnd: uvEnd;
		dsdt: 1 / (uvEnd - uvStart) length;
		privateCalcBoundingBox.
	^uvLine</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id> <category>ops</category>

<body package="CADSM-Geo" selector="magnifySelf:">magnifySelf: aDouble 
	super magnifySelf: aDouble.
	radius := radius * aDouble</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	| aLine |
	super initialize.
	aLine := (CADSM.Geo.CADSMGeoLine new)
				rfstartf: (StMFullColumn zero: 3);
				rfendf: (StMFullColumn zero: 3);
				yourself.
	self _aCurve: aLine</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id> <category>calc</category>

<body package="CADSM-Geo" selector="condition_cglTrimNurbs:">condition_cglTrimNurbs: cglTrimNurbs 
	| tol uvStart uvEnd aStream uvNext uvStarti v aPoint bPoint cPoint dPoint |
	tol := 1.0d-4.
	uvStart := cglTrimNurbs first uvStart.
	uvEnd := cglTrimNurbs last uvEnd.
	^(uvStart - uvEnd) length &lt; tol 
		ifTrue: 
			[aStream := (cglTrimNurbs species new: cglTrimNurbs size) writeStream.
			uvNext := uvStart.
			cglTrimNurbs do: 
					[:glTrimNurbs | 
					uvStarti := glTrimNurbs uvStart.
					(uvNext - uvStarti) length &lt; tol 
						ifFalse: 
							[self name: #debug.
							aStream nextPut: (CADSMGeoNurbsCurve 
										fromStart: uvNext copy
										toEnd: uvStarti copy
										isSpatial: false)].
					aStream nextPut: glTrimNurbs.
					uvNext := glTrimNurbs uvEnd].
			(uvNext - uvStart) length &lt; tol 
				ifFalse: 
					[self name: #debug.
					aStream nextPut: (CADSMGeoNurbsCurve 
								fromStart: uvNext copy
								toEnd: uvStart copy
								isSpatial: false)].
			aStream contents]
		ifFalse: 
			[((uvStart v equal: 0.0d tol: tol) or: [uvStart v equal: 1.0d tol: tol]) 
				ifTrue: 
					[self name: #debug.
					cglTrimNurbs
						addLast: (CADSMGeoNurbsCurve 
									fromStart: uvEnd copy
									toEnd: uvStart copy
									isSpatial: false);
						yourself]
				ifFalse: 
					[self name: #debug.
					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.
					cglTrimNurbs
						addLast: (CADSMGeoNurbsCurve 
									fromStart: aPoint copy
									toEnd: bPoint copy
									isSpatial: false);
						addLast: (CADSMGeoNurbsCurve 
									fromStart: bPoint copy
									toEnd: cPoint copy
									isSpatial: false);
						addLast: (CADSMGeoNurbsCurve 
									fromStart: cPoint copy
									toEnd: dPoint copy
									isSpatial: false);
						yourself]]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoConicalSurface</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="printVerboseOn:">printVerboseOn: aStream 
	aStream
		nextPutAll: 'ConicalSurface';
		cr;
		printVerbose: aRefFrame;
		cr;
		printVerbose: aCurve</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorque</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aMarkerI">aMarkerI
	^aMarkerI</body>

<body package="CADSM-Geo" selector="aMarkerI:">aMarkerI: markeri 
	aMarkerI := markeri</body>

<body package="CADSM-Geo" selector="aMarkerJ">aMarkerJ
	^aMarkerJ</body>

<body package="CADSM-Geo" selector="aMarkerJ:">aMarkerJ: markerj 
	aMarkerJ := markerj</body>

<body package="CADSM-Geo" selector="connectorList:">connectorList: collection 
	collection add: self</body>

<body package="CADSM-Geo" selector="dataClass">dataClass
	^StCAD.StGeo.GEOKineIForceIKineJ</body>

<body package="CADSM-Geo" selector="dataSeriesForChart">dataSeriesForChart
	| kineIs kineJs forceIs index kineIforceIkineJ |
	kineIs := aMarkerI dataSeriesForChart.
	kineJs := aMarkerJ dataSeriesForChart.
	forceIs := self dataSeries.
	^(kineIs isSequenceable and: [kineJs isSequenceable and: [forceIs isSequenceable]])
		ifTrue: 
			[index := 0.
			kineIs
				collect: 
					[:kineI | 
					index := index + 1.
					kineIforceIkineJ := self dataClass new.
					kineIforceIkineJ kineI: (kineIs at: index).
					kineIforceIkineJ forceI: (forceIs at: index).
					kineIforceIkineJ kineJ: (kineJs at: index).
					kineIforceIkineJ]]
		ifFalse: 
			[Dialog warn: 'Simulation data is incomplete. Rerun a simulation.'.
			Array new]</body>

<body package="CADSM-Geo" selector="dataTypes">dataTypes
	^self dataClass new dataTypes</body>

<body package="CADSM-Geo" selector="functionParser">functionParser
	| parser |
	parser := StCAD.StGeo.ForceFunctionParser new.
	parser container: self.
	parser initVariables.
	parser initgeoIJs.
	^parser</body>

<body package="CADSM-Geo" selector="markerI:markerJ:">markerI: markeri markerJ: markerj 
	aMarkerI := markeri.
	aMarkerJ := markerj</body>

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

<body package="CADSM-Geo" selector="name:">name: aString 
	name := aString asSymbol</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorque</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="canUpdateForFrame:">canUpdateForFrame: integer 
	^true</body>

<body package="CADSM-Geo" selector="createMbD">createMbD
	self dataSeries: OrderedCollection new.
	self discontinuities: OrderedCollection new</body>

<body package="CADSM-Geo" selector="dataFromCurrentState">dataFromCurrentState
	| answer |
	answer := CADSMDataForceTorque new.
	answer aFIO: (StMFullColumn zero: 3).
	answer aTIO: (StMFullColumn zero: 3).
	^answer</body>

<body package="CADSM-Geo" selector="dataFromMbD">dataFromMbD
	| aMbDUnits mbdItem answer |
	aMbDUnits := self aMbDUnits.
	mbdItem := self mbdObject.
	answer := CADSMDataForceTorque new.
	answer aFIO: mbdItem aFX * aMbDUnits force.
	answer aTIO: mbdItem aTX * aMbDUnits torque.
	^answer</body>

<body package="CADSM-Geo" selector="dataIntersectLine:tolerance:">dataIntersectLine: geoLine tolerance: tol 
	| forceLine answer |
	forceLine := StCAD.StGeo.GEOLine start: aMarkerI refFrame rOfO
				end: aMarkerJ refFrame rOfO.
	forceLine refFrame: self interface worldFrame.
	answer := forceLine dataIntersectLine: geoLine tolerance: tol.
	forceLine release.
	^answer</body>

<body package="CADSM-Geo" selector="deleteMbD">deleteMbD
	super deleteMbD.
	aMarkerI deleteMbD.
	aMarkerJ deleteMbD</body>

<body package="CADSM-Geo" selector="storeInputFromMbD">storeInputFromMbD
	"Do nothing."</body>

<body package="CADSM-Geo" selector="storeInputState">storeInputState
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateForFrame1:">updateForFrame1: integer 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateForFrame:">updateForFrame: integer 
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromInitiallyAssembledState">updateFromInitiallyAssembledState
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromInputState">updateFromInputState
	"Do nothing."</body>

<body package="CADSM-Geo" selector="updateFromMbD">updateFromMbD
	| data |
	data := self dataFromMbD.
	self dataSeries add: data</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorque</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isConnectedTo:">isConnectedTo: markerList 
	^(markerList includes: aMarkerI)
		or: [markerList includes: aMarkerJ]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorque</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	aStream storeLevel: level title: self nameString.
	aStream
		storeLevel: level + 1
		title: 'Name'
		object: self name.
	aStream
		storeLevel: level + 1
		title: 'MarkerI'
		object: aMarkerI fullName.
	aStream
		storeLevel: level + 1
		title: 'MarkerJ'
		object: aMarkerJ fullName</body>

<body package="CADSM-Geo" selector="storePOVdatCurrentOn:">storePOVdatCurrentOn: aStream 
	| dataSeries fullNamePOV series |
	dataSeries := Array with: self dataFromCurrentState.
	fullNamePOV := self fullNamePOV.
	series := dataSeries collect: [:data | data aFIO].
	aStream storePOVTitle: fullNamePOV , '_FXonI'
		series: (series collect: [:data | data at: 1]).
	aStream storePOVTitle: fullNamePOV , '_FYonI'
		series: (series collect: [:data | data at: 2]).
	aStream storePOVTitle: fullNamePOV , '_FZonI'
		series: (series collect: [:data | data at: 3]).
	series := dataSeries collect: [:data | data aTIO].
	aStream storePOVTitle: fullNamePOV , '_TXonI'
		series: (series collect: [:data | data at: 1]).
	aStream storePOVTitle: fullNamePOV , '_TYonI'
		series: (series collect: [:data | data at: 2]).
	aStream storePOVTitle: fullNamePOV , '_TZonI'
		series: (series collect: [:data | data at: 3])</body>

<body package="CADSM-Geo" selector="storePOVOn:level:">storePOVOn: aStream level: level 
	aStream storePOVLevel: level
		title: ('// &lt;1s&gt;' expandMacrosWith: self fullNamePOV)</body>

<body package="CADSM-Geo" selector="storePOVTimeSeriesOn:">storePOVTimeSeriesOn: aStream 
	| dataSeries fullNamePOV series |
	dataSeries := self dataSeries.
	fullNamePOV := self fullNamePOV.
	series := dataSeries collect: [:data | data aFIO].
	aStream storePOVTitle: fullNamePOV , '_FXonI'
		series: (series collect: [:data | (data at: 1) ]).
	aStream storePOVTitle: fullNamePOV , '_FYonI'
		series: (series collect: [:data | (data at: 2) ]).
	aStream storePOVTitle: fullNamePOV , '_FZonI'
		series: (series collect: [:data | (data at: 3) ]).
	series := dataSeries collect: [:data | data aTIO].
	aStream storePOVTitle: fullNamePOV , '_TXonI'
		series: (series collect: [:data | (data at: 1) ]).
	aStream storePOVTitle: fullNamePOV , '_TYonI'
		series: (series collect: [:data | (data at: 2) ]).
	aStream storePOVTitle: fullNamePOV , '_TZonI'
		series: (series collect: [:data | (data at: 3) ])</body>

<body package="CADSM-Geo" selector="storeTimeSeriesOn:">storeTimeSeriesOn: aStream 
	| dataSeries series |
	aStream nextPutAll: self nameString; nextPutAll: 'Series'; space; nextPutAll: self fullName; cr.
	dataSeries := self dataSeries.
	series := dataSeries collect: [:data | data aFIO].
	aStream
		storeTitle: 'FXonI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	aStream
		storeTitle: 'FYonI'
		input: 0
		series: (series collect: [:data | data at: 2]).
	aStream
		storeTitle: 'FZonI'
		input: 0
		series: (series collect: [:data | data at: 3]).
	series := dataSeries collect: [:data | data aTIO].
	aStream
		storeTitle: 'TXonI'
		input: 0
		series: (series collect: [:data | data at: 1]).
	aStream
		storeTitle: 'TYonI'
		input: 0
		series: (series collect: [:data | data at: 2]).
	aStream
		storeTitle: 'TZonI'
		input: 0
		series: (series collect: [:data | data at: 3])</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorque class</class-id> <category>instance creation</category>

<body package="CADSM-Geo" selector="markerI:markerJ:">markerI: markeri markerJ: markerj 
	^super new markerI: markeri markerJ: markerj</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueInLine</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="cut">cut
	aSup cutForceTorque: self.
	super cut</body>

<body package="CADSM-Geo" selector="tensionFunc">tensionFunc
	^tensionFunc</body>

<body package="CADSM-Geo" selector="tensionFunc:">tensionFunc: userFunc 
	tensionFunc := userFunc</body>

<body package="CADSM-Geo" selector="twistFunc">twistFunc
	^twistFunc</body>

<body package="CADSM-Geo" selector="twistFunc:">twistFunc: userFunc 
	twistFunc := userFunc</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aSup addForceTorque: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueInLine</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isForce">isForce
	^true</body>

<body package="CADSM-Geo" selector="isTorque">isTorque
	^false</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueInLine</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| eFrmI eFrmJ mbdForceTorqueInLine tension parser stack func twist |
	super createMbD.
	eFrmI := aMarkerI mbdObject.
	eFrmJ := aMarkerJ mbdObject.
	mbdForceTorqueInLine := StCAD.StMbD.ForceTorqueInLine onFrmI: eFrmI andFrmJ: eFrmJ.
	mbdForceTorqueInLine name: self fullName.
	tension := tensionFunc notNil
				ifTrue: 
					[func := tensionFunc isUserFunction
								ifTrue: 
									[parser := self functionParser.
									stack := parser
												parseUserFunction: tensionFunc
												notifying: nil
												ifFail: nil.
									stack last]
								ifFalse: [tensionFunc].
					(func / self aMbDUnits force) createMbD simplified]
				ifFalse: [nil].
	mbdForceTorqueInLine tension: tension.
	twist := twistFunc notNil
				ifTrue: 
					[func := twistFunc isUserFunction
								ifTrue: 
									[parser := self functionParser.
									stack := parser
												parseUserFunction: twistFunc
												notifying: nil
												ifFail: nil.
									stack last]
								ifFalse: [twistFunc].
					(func / self aMbDUnits torque) createMbD simplified]
				ifFalse: [nil].
	mbdForceTorqueInLine twist: twist.
	mbdForceTorqueInLine submitToSystem.
	self mbdObject: mbdForceTorqueInLine.
	[mbdForceTorqueInLine initializeLocally]
		on: self messageNotUnderstoodSignal
		do: 
			[:ex | 
			| sel |
			sel := ex parameter selector.
			sel == #isKineIJ
				ifTrue: 
					[Dialog warn: 'ForceTorque function cannot use a ''geoIJ'' that also uses marker I of a motion constraint.&lt;n&gt;Just create extra markers and geoIJs.' expandMacros.
					StCAD.StMbD.SimulationStoppingError raiseSignal]
				ifFalse: [ex pass]]</body>

<body package="CADSM-Geo" selector="tension">tension
	| parser stack |
	^tensionFunc notNil
		ifTrue: [tensionFunc isUserFunction
				ifTrue: 
					[parser := self functionParser.
					stack := parser
								parseUserFunction: tensionFunc
								notifying: nil
								ifFail: nil.
					stack last]
				ifFalse: [tensionFunc]]
		ifFalse: [nil]</body>

<body package="CADSM-Geo" selector="twist">twist
	| parser stack |
	^twistFunc notNil
		ifTrue: [twistFunc isUserFunction
				ifTrue: 
					[parser := self functionParser.
					stack := parser
								parseUserFunction: twistFunc
								notifying: nil
								ifFail: nil.
					stack last]
				ifFalse: [twistFunc]]
		ifFalse: [nil]</body>

<body package="CADSM-Geo" selector="validateFormulas">validateFormulas
	self tension.
	self twist</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueInLine</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream
		storeLevel: level + 1
		title: 'tension'
		object: tensionFunc.
	aStream
		storeLevel: level + 1
		title: 'twist'
		object: twistFunc</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueInLine class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'InLineForceTorque'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueGeneral</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	aMarkerK := #I.
	aFIeKe := StMFullColumn new: 3.
	aTIeKe := StMFullColumn new: 3</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueGeneral</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="aFIeKe">aFIeKe
	^aFIeKe</body>

<body package="CADSM-Geo" selector="aFIeKe:">aFIeKe: col 
	aFIeKe := col</body>

<body package="CADSM-Geo" selector="aTIeKe">aTIeKe
	^aTIeKe</body>

<body package="CADSM-Geo" selector="aTIeKe:">aTIeKe: col 
	aTIeKe := col</body>

<body package="CADSM-Geo" selector="cut">cut
	aSup cutForceTorque: self.
	super cut</body>

<body package="CADSM-Geo" selector="markerK">markerK
	^aMarkerK</body>

<body package="CADSM-Geo" selector="markerK:">markerK: markerk 
	aMarkerK := markerk</body>

<body package="CADSM-Geo" selector="uncut">uncut
	aSup addForceTorque: self</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueGeneral</class-id> <category>testing</category>

<body package="CADSM-Geo" selector="isForce">isForce
	^true</body>

<body package="CADSM-Geo" selector="isTorque">isTorque
	^true</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueGeneral</class-id> <category>DYN</category>

<body package="CADSM-Geo" selector="aFIeKeFunc">aFIeKeFunc
	| aFIeKeFunc aFIeKei aFIeKeiFunc parser stack func |
	aFIeKeFunc := StCAD.StMath.StMFullColumn new: 3.
	1 to: 3
		do: 
			[:i | 
			aFIeKei := aFIeKe at: i.
			aFIeKei notNil
				ifTrue: 
					[aFIeKeiFunc := aFIeKei isUserFunction
								ifTrue: 
									[parser := self functionParser.
									stack := parser
												parseUserFunction: aFIeKei
												notifying: nil
												ifFail: nil.
									func := stack last.
									func]
								ifFalse: [aFIeKei].
					aFIeKeFunc at: i put: aFIeKeiFunc]].
	^aFIeKeFunc</body>

<body package="CADSM-Geo" selector="aTIeKeFunc">aTIeKeFunc
	| aTIeKeFunc aTIeKei aTIeKeiFunc parser stack func |
	aTIeKeFunc := StCAD.StMath.StMFullColumn new: 3.
	1 to: 3
		do: 
			[:i | 
			aTIeKei := aTIeKe at: i.
			aTIeKei notNil
				ifTrue: 
					[aTIeKeiFunc := aTIeKei isUserFunction
								ifTrue: 
									[parser := self functionParser.
									stack := parser
												parseUserFunction: aTIeKei
												notifying: nil
												ifFail: nil.
									func := stack last.
									func]
								ifFalse: [aTIeKei].
					aTIeKeFunc at: i put: aTIeKeiFunc]].
	^aTIeKeFunc</body>

<body package="CADSM-Geo" selector="createMbD">createMbD
	| eFrmI eFrmJ mbdForce efrmK aFIeKeFunc aFIeKei aFIeKeiFunc parser stack func aTIeKeFunc aTIeKei aTIeKeiFunc |
	super createMbD.
	eFrmI := aMarkerI mbdObject.
	eFrmJ := aMarkerJ mbdObject.
	mbdForce := aMarkerK == #O
				ifTrue: [StCAD.StMbD.ForceTorqueGeneral onFrmI: eFrmI andFrmJ: eFrmJ]
				ifFalse: 
					[efrmK := aMarkerK == #J
								ifTrue: [eFrmJ]
								ifFalse: [eFrmI].
					StCAD.StMbD.ForceTorqueGeneral
						onFrmI: eFrmI
						andFrmJ: eFrmJ
						wrtFrmK: efrmK].
	mbdForce name: self fullName.
	aFIeKeFunc := StCAD.StMath.StMFullColumn new: 3.
	1 to: 3
		do: 
			[:i | 
			aFIeKei := aFIeKe at: i.
			aFIeKei notNil
				ifTrue: 
					[aFIeKeiFunc := aFIeKei isUserFunction
								ifTrue: 
									[parser := self functionParser.
									stack := parser
												parseUserFunction: aFIeKei
												notifying: nil
												ifFail: nil.
									func := stack last.
									func]
								ifFalse: [aFIeKei].
					aFIeKeiFunc := (aFIeKeiFunc / self aMbDUnits force) createMbD simplified.
					aFIeKeFunc at: i put: aFIeKeiFunc]].
	mbdForce forceFunctions: aFIeKeFunc.
	aTIeKeFunc := StCAD.StMath.StMFullColumn new: 3.
	1 to: 3
		do: 
			[:i | 
			aTIeKei := aTIeKe at: i.
			aTIeKei notNil
				ifTrue: 
					[aTIeKeiFunc := aTIeKei isUserFunction
								ifTrue: 
									[parser := self functionParser.
									stack := parser
												parseUserFunction: aTIeKei
												notifying: nil
												ifFail: nil.
									func := stack last.
									func]
								ifFalse: [aTIeKei].
					aTIeKeiFunc := (aTIeKeiFunc / self aMbDUnits torque) createMbD simplified.
					aTIeKeFunc at: i put: aTIeKeiFunc]].
	mbdForce torqueFunctions: aTIeKeFunc.
	mbdForce submitToSystem.
	self mbdObject: mbdForce.
	[mbdForce initializeLocally]
		on: self messageNotUnderstoodSignal
		do: 
			[:ex | 
			| sel |
			sel := ex parameter selector.
			sel == #isKineIJ
				ifTrue: 
					[Dialog warn: 'ForceTorque function cannot use a ''geoIJ'' that also uses marker I of a motion constraint.&lt;n&gt;Just create extra markers and geoIJs.' expandMacros.
					StCAD.StMbD.SimulationStoppingError raiseSignal]
				ifFalse: [ex pass]]</body>

<body package="CADSM-Geo" selector="validateFormulas">validateFormulas
	self aFIeKeFunc.
	self aTIeKeFunc</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueGeneral</class-id> <category>printing</category>

<body package="CADSM-Geo" selector="storeOn:level:">storeOn: aStream level: level 
	super storeOn: aStream level: level.
	aStream
		storeLevel: level + 1
		title: 'FxOnI'
		object: (aFIeKe at: 1).
	aStream
		storeLevel: level + 1
		title: 'FyOnI'
		object: (aFIeKe at: 2).
	aStream
		storeLevel: level + 1
		title: 'FzOnI'
		object: (aFIeKe at: 3).
	aStream
		storeLevel: level + 1
		title: 'TxOnI'
		object: (aTIeKe at: 1).
	aStream
		storeLevel: level + 1
		title: 'TyOnI'
		object: (aTIeKe at: 2).
	aStream
		storeLevel: level + 1
		title: 'TzOnI'
		object: (aTIeKe at: 3).
	aStream
		storeLevel: level + 1
		title: 'MarkerK'
		object: (aMarkerK notNil
				ifTrue: [aMarkerK]
				ifFalse: [#I])</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoForceTorqueGeneral class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'GeneralForceTorque'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoInPlaneJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDPointInPlaneJoint</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPointInPlaneJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'PointInPlaneJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoLineInPlaneJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="nameString">nameString
	^'LineInPlaneJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoPlanarJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDPlanarJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'PlanarJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoNoRotationJoint class</class-id> <category>accessing</category>

<body package="CADSM-Geo" selector="mbdClass">mbdClass
	^MbDNoRotationJoint</body>

<body package="CADSM-Geo" selector="nameString">nameString
	^'NoRotationJoint'</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSupItem</class-id> <category>accessing</category>

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

	aSub removeSup.
	cSub add: aSub.
	aSub aSup: self.
	^aSub</body>

<body package="CADSM-Geo" selector="removeSub:">removeSub: aSub 
	^(cSub remove: aSub ifAbsent: [nil]) ifNotNil: 
			[:aaSub | 
			aaSub aSup: nil.
			aaSub]</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSupItem</class-id> <category>initialize-release</category>

<body package="CADSM-Geo" selector="initialize">initialize
	super initialize.
	cSub := CADSM.Misc.CADSMMiscOrderedSet new</body>
</methods>

<methods>
<class-id>CADSM.Geo.CADSMGeoSupItem</class-id> <category>copying</category>

<body package="CADSM-Geo" selector="postCopy">postCopy
	super postCopy.
	cSub := IdentitySet new</body>
</methods>

<initialize>
<class-id>CADSM.Geo.CADSMGeoNurbsCurve</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>GEOFunction</name>
<environment>StCAD.StGeo</environment>
<super>StCAD.CADFunction</super>
<private>false</private>
<indexed-type>none</indexed-type>
<inst-vars></inst-vars>
<class-inst-vars></class-inst-vars>
<imports></imports>
<category>GEO</category>
<attributes>
<package>xGeo</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>CADSMAbstractCylindricalFrame</name>
<environment>Smalltalk</environment>
<super>CADSMCoordinateFrame</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>CADSMAbstractSphericalFrame</name>
<environment>Smalltalk</environment>
<super>CADSMCoordinateFrame</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>CADSMAbstractCartesianFrame</name>
<environment>Smalltalk</environment>
<super>CADSMCoordinateFrame</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>

</st-source>
