Imports System
Imports System.IO

' The CAt3dData class shows how to use the functions that are in
' the AccuTrans 3D DLL.  Do NOT include this class in your application which
' will use the DLL.  Cut and Paste any appropriate code segments from this
' class to your application as required to fit the code design for your
' application.

Public Class CAt3dData
	'
	Const LEN_LAYER_NAME As Int32 = 80
	Const MAX_PATH As Int32 = 260
	Const LEN_XYZ_DELIMITERS As Int32 = 40

	Dim redKnight As CRedKnight
	Dim greenKnight As CGreenKnight
	Dim blueKnight As CBlueKnight
	Dim greenMonk As CGreenMonk
	Dim blueMonk As CBlueMonk
	Dim multiMatKnight As CMultiMatKnight

	Structure XYZ
		Public x As Double
		Public y As Double
    Public z As Double

    Public Sub New(ByVal x As Double, ByVal y As Double, ByVal z As Double)
      Me.x = x
      Me.y = y
      Me.z = z
    End Sub
	End Structure

	Structure FLOAT_XYZ
		Public x As Single
		Public y As Single
    Public z As Single

    Public Sub New(ByVal x As Single, ByVal y As Single, ByVal z As Single)
      Me.x = x
      Me.y = y
      Me.z = z
    End Sub
	End Structure

	Structure XYZ_UV
		Public x As Double
		Public y As Double
		Public z As Double
		Public u As Single
		Public v As Single
	End Structure

	Structure FLOAT_XYZ_UV
		Public x As Single
		Public y As Single
		Public z As Single
		Public u As Single
		Public v As Single
	End Structure

	Structure EDGE
		Public p0 As Int32
		Public p1 As Int32
	End Structure

	Structure TRIANGLE
		Public p0 As Int32
		Public p1 As Int32
		Public p2 As Int32
	End Structure

	Structure UV
		Public u As Single
		Public v As Single
	End Structure

	Structure UV_TRI
		Public u0 As Single
		Public v0 As Single
		Public u1 As Single
		Public v1 As Single
		Public u2 As Single
		Public v2 As Single
	End Structure

	Structure VNORMAL
		Public x As Single
		Public y As Single
		Public z As Single
	End Structure

	Structure VNORMAL_TRI
		Public x0 As Single
		Public y0 As Single
		Public z0 As Single
		Public x1 As Single
		Public y1 As Single
		Public z1 As Single
		Public x2 As Single
		Public y2 As Single
		Public z2 As Single
	End Structure

	Structure VCOLOR
		Public red As Single
		Public green As Single
		Public blue As Single
		Public alpha As Single
	End Structure

	Structure VCOLOR_TRI
		Public red0 As Single
		Public green0 As Single
		Public blue0 As Single
		Public alpha0 As Single
		Public red1 As Single
		Public green1 As Single
		Public blue1 As Single
		Public alpha1 As Single
		Public red2 As Single
		Public green2 As Single
		Public blue2 As Single
		Public alpha2 As Single
	End Structure

	Structure RGB
		Public red As Single
		Public green As Single
    Public blue As Single

    Public Sub New(ByVal red As Single, ByVal green As Single, ByVal blue As Single)
      Me.red = red
      Me.green = green
      Me.blue = blue
    End Sub
	End Structure

	Structure RGBA
		Public red As Single
		Public green As Single
		Public blue As Single
		Public alpha As Single
	End Structure

	Const OGL_LIGHT_COUNT As Int32 = 8

	Structure OGL_LIGHT
		Public enabledFlag As Int32
		Public ambient As RGBA
		Public diffuse As RGBA
		Public specular As RGBA
		Public position As FLOAT_XYZ
	End Structure

	Structure Data_3D
		Public name As String
		Public parentName As String
		'
		Public pivotPoint As XYZ
		'
		Public PCount3D As Int32		 ' for 3D faces
		Public TCount As Int32
		Public xyz3D() As XYZ
		Public xyzFloat3D() As FLOAT_XYZ
		Public xyzIndex() As TRIANGLE
		Public uv_tri() As uv_tri
		Public vnorm_tri() As VNORMAL_TRI
		Public vcolor_tri() As vcolor_tri
		Public rgb() As rgb
		'
		Public uvCount As Int32
		Public vnormCount As Int32
		Public vcolorCount As Int32
		Public xyz_uvCount As Int32
		Public uvPresentFlag As Int32		 ' use with XYZ_UV
		Public uv() As uv
		Public vnorm() As VNORMAL
		Public vcolor() As vcolor
		Public xyz_uv() As xyz_uv
		Public xyzFloat_uv() As FLOAT_XYZ_UV
		Public uvIndex() As TRIANGLE
		Public vnormIndex() As TRIANGLE
		Public vcolorIndex() As TRIANGLE
		'
		Public PCount2D As Int32		 ' for 2D edges
		Public ECount2D As Int32
		Public xyz2D() As XYZ
		Public xyzFloat2D() As FLOAT_XYZ
		Public edge2D() As EDGE
		'
		Public PCountCloud As Int32		' for point cloud (no edges or faces)
		Public xyzCloud() As XYZ
		Public xyzFloatCloud() As FLOAT_XYZ
		'
		Public dxfColor As Int32
		Public doubleSided As Int32
		Public rwxGeometrySampling As Int32
		Public rwxLightSampling As Int32
		Public rwxTextureModes As Int32
		Public rwxTag As Int32
		Public ambient1 As Single
		Public ambientRGB As rgb
		Public colorRGB As rgb
		Public diffuse1 As Single
		Public diffuseRGB As rgb
		Public reflection1 As Single
		Public reflectionRGB As rgb
		Public specular1 As Single
		Public specularRGB As rgb
		Public emissiveRGB As rgb
		Public roughness As Single
		Public shininess As Single
		Public transparency1 As Single
		Public transparencyRGB As rgb
		Public indexRefraction As Single
		Public creaseAngle As Single
		Public texturePathName As String
		Public maskPathName As String
	End Structure

	Structure Object_MinMax
		Public minX As Double
		Public maxX As Double
		Public minY As Double
		Public maxY As Double
		Public minZ As Double
		Public maxZ As Double
	End Structure

	Structure Layer_MinMax
		Public cloudVertexCount As Int32
		Public lineVertexCount As Int32
		Public meshVertexCount As Int32
		Public lineCount As Int32
		Public triangleCount As Int32
		'
		Public minX As Double
		Public maxX As Double
		Public minY As Double
		Public maxY As Double
		Public minZ As Double
		Public maxZ As Double
	End Structure

	Structure Mesh_To_Landscape
		Public stretchXFlag As Int32
		Public stretchYFlag As Int32
		Public convertFlag As Int32
		Public addCloudFlag As Int32
		Public dropFacesFlag As Int32
		Public addBaseFlag As Int32
		Public addUVFlag As Int32
		Public writeXYZFlag As Int32
		'
		Public minX As Double
		Public maxX As Double
		Public sizeX As Double
		'
		Public minY As Double
		Public maxY As Double
		Public sizeY As Double
		'
		Public minZ As Double
		Public maxZ As Double
		Public sizeZ As Double
		'
		Public xSpacing As Double
		Public ySpacing As Double
		'
		Public xCount As Int32
		Public yCount As Int32
		Public vertCount As Int32
		Public edgeCount As Int32
		Public triangleCount As Int32
		'
		Public newSizeX As Double
		Public newSizeY As Double
		Public lastXSpacing As Double
		Public lastYSpacing As Double
		'
		Public dropElevation As Double
		Public baseThickness As Double
	End Structure

	Public AE As New System.Text.ASCIIEncoding()
	' ---
	Public dllOpen As Int32 = 0
	' ---
	Public dataCount As Int32 = 0
	Dim dataList() As Data_3D = Nothing
	' ---
	Public fileLoaded As Int32 = 0
	Public inName As String = Nothing
	Public outName As String = Nothing
	' ---
	Dim readType As At3d_InType = At3d_InType.INTYPE_DXF
	Dim writeType As At3d_OutType = At3d_OutType.OUTTYPE_DXF
	' ---
	Public alignName As String = Nothing
	Public alignNextLayer As Int32 = 0
	' ---
	Public fontPath As String = Nothing
  Public dxfFontName As String = "Arial"
  '
	Public vrmlSerifFontName As String = "Times New Roman"
	Public vrmlSansFontName As String = "Microsoft Sans Serif"
  Public vrmlTypewriterFontName As String = "Courier New"
  '
  Public textText As String = "Test"
  Public textUnicodeText As String = "Unicode"
  '
  Public textFaceName As String = "Arial"
  '
	Public textLayersFlag As Int32 = 0
	Public textStencilFlag As Int32 = 0
  Public textPlusCoreFlag As Int32 = 0
  Public textReverseOutlinesFlag As Int32 = 0
  Public textOnCurveFlag As Int32 = 0
  Public textOrigVertsFlag As Int32 = 0
  Public textAllCharsFlag As Int32 = 0
	Public textReduceFlag As Int32 = 1
	Public textJoinFlag As Int32 = 1
	Public textFaceFlag As Int32 = 1
	Public textExtrudeFlag As Int32 = 1
	Public textBoldFlag As Int32 = 0
	Public textItalicFlag As Int32 = 0
	Public textPoints As Int32 = 3
	Public textHeight As Double = 1.0
	Public textDepth As Double = 0.1
	Public textBorder As Double = 0.25
	' ---
	Public vrmlTextFlag As Int32 = 0
	' ---
  Public outputAvatarFlag As Int32 = 0
  Public outputHierarchyFlag As Int32 = 0
	Public oneLayerPerFileFlag As Int32 = 0
	Public multiMaterialFlag As Int32 = 0
	Public quadFlag As Int32 = 0
	Public uvFlag As Int32 = 0
	Public vnormFlag As Int32 = 0
	Public vcolorFlag As Int32 = 0
	Public savePointCloudFlag As Int32 = 0
	Public save2DFlag As Int32 = 0
	Public autoDivideLayersFlag As Int32 = 0
	Public noIndentFlag As Int32 = 0
	Public textAsTextFlag As Int32 = 0
	' ---
	Public bufferReadFlag As Int32 = 0
	Public bufferWriteFlag As Int32 = 0
	' ---
	Public transferFromTypeFlag As Int32 = At3d_TransferFromFlag.TYPE_BASIC
	Public vertexFloatTransferFlag As Int32 = 0
	' ---
	Public removeVerticesFlag As Int32 = 1
	Public removeFacesFlag As Int32 = 1
	' ---
	Public useDxfTextFlag As Int32 = 0
	' ---
	Public outType3dmf As Int32 = 0
	Public pixelFlag3dmf As Int32 = 0
	' ---
	Public showReadMessagesFlag As Int32 = 0
	Public showSaveMessagesFlag As Int32 = 0
	' ---
	Public triQuadNormalAngle As Double = 5.0
	Public triQuadEdgeAngle As Double = 130.0
	' ---
	Public useOglFlag As Int32 = 1
  Public oglDebugMsgFlag As Int32 = 0
  Public pauseAtOglSnapshotFlag As Int32 = 0
	Public twoSidedLightingFlag As Int32 = 1
	Public cullBackFacesFlag As Int32 = 0
	Public displayTexturesFlag As Int32 = 1
	Public defaultTextureFlag As Int32 = 0
	Public oglReplaceFlag As Int32 = 0
	Public useWhiteBaseFlag As Int32 = 1
	Public textureSearchFlag As Int32 = 0
	Public textureNameMatchFlag As Int32 = 1
	Public relocateTexturesFlag As Int32 = 0
	Public saveTexturePathFlag As Int32 = 1
	Public partialTexturePathFlag As Int32 = 0
	' ---  
	Public cameraXViewPoint As Double = 0.0
	Public cameraYViewPoint As Double = 0.0
	Public cameraZViewPoint As Double = 0.0
	' ---
	Public cameraRotateSpeed As Int32 = At3d_CameraFlags.CAMERA_ROTATE_SPEED_2
	Public cameraXAngle As Double = 0.0
	Public cameraYAngle As Double = 0.0
	Public cameraZAngle As Double = 0.0
	Public cameraStepAngle As Double = 5.0
	' ---
	Public cameraInitialDistance As Double = 0.0
	Public cameraDistance As Double = 0.0
	Public cameraZoomSpeed As Int32 = At3d_CameraFlags.CAMERA_ZOOM_SPEED_6
	Public reverseZoomDirectionFlag As Int32 = 0
	Public reversePanDirectionFlag As Int32 = 0
	' ---
	Public cameraFieldOfView As Double = 30.0
	Public cameraStepFOV As Double = 1.0
	' ---
	Public cameraXPan As Int32 = 0
	Public cameraZPan As Int32 = 0
	Public cameraStepPan As Int32 = 1
	' ---
	Public objectMinMax As Object_MinMax

	Public objectCenter As XYZ
	Public objectEdit As XYZ

	Public originRotateFlag As Int32 = 0
	Public drawObjectAxesFlag As Int32 = 0
	' ---
	Public defaultAmbient1 As Single
	Public defaultAmbientRGB As RGB
	Public defaultColorRGB As RGB
	Public defaultDiffuse1 As Single
	Public defaultDiffuseRGB As RGB
	Public defaultSpecular1 As Single
	Public defaultSpecularRGB As RGB
	Public defaultEmissiveRGB As RGB
	Public defaultRoughness As Single
	Public defaultShininess As Single
	Public defaultTransparency1 As Single
	Public defaultTransparencyRGB As RGB
	Public defaultIndexOfRefraction As Single
	Public defaultCreaseAngle As Single
	Public defaultDxfColor As Int32
	Public defaultDoubleSided As Int32
	Public defaultRwxGeometrySampling As Int32
	Public defaultRwxLightSampling As Int32
	Public defaultRwxTextureModes As Int32
	Public defaultRwxClumpTag As Int32
	Public defaultRwxFaceTag As Int32
	' ---
	Public inCount As Int32
	Public inIndex As Int32
	Public inType(48) As Int32
	Public inLabel(48) As String
	Public inExt(48) As String
	' ---
	Public outCount As Int32
	Public outIndex As Int32
	Public outType(45) As Int32
	Public outLabel(45) As String
	Public outExt(45) As String
	' ---
	Public oglRenderCount As Int32
	Public oglRenderIndex As Int32
	Public oglRenderType(9) As Int32
	Public oglRenderLabel(9) As String
	' ---
	Public backgroundCount As Int32
	Public backgroundIndex As Int32 = 3
	Public backgroundType(4) As Int32
	Public backgroundLabel(4) As String
	Public backgroundColor As RGB
	' ---
	Public textureTypeCount As Int32
	Public textureTypeIndex As Int32 = 0
	Public textureType(2) As Int32
	Public textureTypeLabel(2) As String
	Public textureCenter(1) As Single
	Public textureRotation As Single
	Public textureScale(1) As Single
	Public textureTranslation(1) As Single
	' ---
	Public useFilmstripFlag As Int32 = 0
	Public filmstripTimerFlag As Int32 = 0
	' ---
	Public useAmbient1Flag As Int32 = 0
	Public useDiffuse1Flag As Int32 = 0
	Public useReflection1Flag As Int32 = 0
	Public useSpecular1Flag As Int32 = 0
	Public useTransparency1Flag As Int32 = 0
	' ---
	Public demBitsPerPixel As Int32 = 8
	Public demColumns As Int32 = 0
	Public demRows As Int32 = 0
	Public demXSpacing As Double = 0.0
	Public demYSpacing As Double = 0.0
	Public demMinHeight As Double = 0.0
	Public demMaxHeight As Double = 0.0
	Public demXOffset As Int32 = 0
	Public demYOffset As Int32 = 0
	Public demSeaLevelFlag As Int32 = 0
	Public demBelowFactor As Single = 10.0
	Public demAboveFactor As Single = 10.0
	' ---
	Public extrudeModeFlag As Int32 = 0
	Public bevelSetsFlag As Int32 = 0
	Public textName(LEN_LAYER_NAME - 1) As Byte
	Public textNextLayer As Int32 = 0
	' ---
	Public editName(LEN_LAYER_NAME - 1) As Byte
	Public editNextLayer As Int32 = 0
	' ---
	Public editMoveVertexX As Double = 0.0
	Public editMoveVertexY As Double = 0.0
	Public editMoveVertexZ As Double = 0.0
	Public editMoveVertexStep As Double = 1.0
	' ---
	Public editRotateXAngle As Double = 0.0
	Public editRotateYAngle As Double = 0.0
	Public editRotateZAngle As Double = 0.0
	Public editRotateStepAngle As Double = 5.0
	' ---
	Public editScaleXFactor As Double = 1.0
	Public editScaleYFactor As Double = 1.0
	Public editScaleZFactor As Double = 1.0
	Public editScaleStepFactor As Double = 0.1
	' ---
	Public editGridSize As Double = 0.01
	' ---
	Public editSnapKeepRelativeFlag As Int32 = 1
	' ---
	Public upperBevelsCount As Int32 = 0
	Public lowerBevelsCount As Int32 = 0

	Const BEVELS_ARRAY_TOTAL As Int32 = 20
	Public upperBevelsWidth(BEVELS_ARRAY_TOTAL) As Double
	Public upperBevelsHeight(BEVELS_ARRAY_TOTAL) As Double
	Public lowerBevelsWidth(BEVELS_ARRAY_TOTAL) As Double
	Public lowerBevelsHeight(BEVELS_ARRAY_TOTAL) As Double
	' ---
	Public meshToLandscape As Mesh_To_Landscape
	' ---
	Public extrude2D_open As Int32 = 0
	Public extrude2D_typeFlag As Int32 = At3d_Extrude2DFlags.EXTRUDE_PSEUDO2D_NORMAL
	Public extrude2D_minMax(5) As Double
	Public extrude2D_xRotation As Double = 0.0
	Public extrude2D_yRotation As Double = 0.0
	Public extrude2D_zRotation As Double = 0.0
	Public extrude2D_thickness As Double = 0.0
	Public extrude2D_adjustLocation As Double = 0.0
	Public extrude2D_stepAngle As Double = 5.0
	Public extrude2D_layerPtr As Int32 = 0
	Public extrude2D_layerName(LEN_LAYER_NAME - 1) As Byte
	' ---
  Public vrmlByChiefArchitectFlag As Int32 = 0
  Public vrmlMiterJointExtrusionFlag As Int32 = 0
  ' ---
	Public kerkytheaUseRadianceFlag As Int32 = 1
	Public kerkytheaRadianceEmitterFlag As Int32 = 0
	Public kerkytheaUsePngAlphaMasksFlag As Int32 = 0
	Public kerkytheaDirectionalAsSpotFlag As Int32 = 1
	Public kerkytheaPointAsSpotFlag As Int32 = 0
	Public kerkytheaPointUpFlag As Int32 = 0
	Public kerkytheaDirectionalAttenuationFlag As Int32 = 1
	Public kerkytheaPointAttenuationFlag As Int32 = 1
	Public kerkytheaSpotAttenuationFlag As Int32 = 1
	Public kerkytheaSpotReplaceFlag As Int32 = 0
	Public kerkytheaSpotUseHotFractionFlag As Int32 = 1
	Public kerkytheaDirectionalShadowFlag As Int32 = 1
	Public kerkytheaDirectionalSoftShadowFlag As Int32 = 1
	Public kerkytheaDirectionalGlobalPhotonsFlag As Int32 = 1
	Public kerkytheaDirectionalCausticPhotonsFlag As Int32 = 1
	Public kerkytheaDirectionalNegativeFlag As Int32 = 0
	Public kerkytheaPointShadowFlag As Int32 = 1
	Public kerkytheaPointSoftShadowFlag As Int32 = 1
	Public kerkytheaPointGlobalPhotonsFlag As Int32 = 1
	Public kerkytheaPointCausticPhotonsFlag As Int32 = 1
	Public kerkytheaPointNegativeFlag As Int32 = 0
	Public kerkytheaSpotShadowFlag As Int32 = 1
	Public kerkytheaSpotSoftShadowFlag As Int32 = 1
	Public kerkytheaSpotGlobalPhotonsFlag As Int32 = 1
	Public kerkytheaSpotCausticPhotonsFlag As Int32 = 1
	Public kerkytheaSpotNegativeFlag As Int32 = 0

	Public kerkytheaDirectionalMultiplier As Single = 1.0
	Public kerkytheaPointMultiplier As Single = 1.0
	Public kerkytheaSpotMultiplier As Single = 1.0
	Public kerkytheaDirectionalFallOff As Single = 140.0
	Public kerkytheaPointFallOff As Single = 120.0
	Public kerkytheaSpotFallOff As Single = 130.0
	Public kerkytheaDirectionalHotSpot As Single = 80.0
	Public kerkytheaPointHotSpot As Single = 30.0
	Public kerkytheaSpotHotSpot As Single = 60.0
	Public kerkytheaSpotHotFraction As Single = 0.5
	Public kerkytheaDirectionalRadius As Single = 0.2
	Public kerkytheaPointRadius As Single = 0.2
	Public kerkytheaSpotRadius As Single = 0.2
	' ---
	Public xyzDelimiters As String = ", ;"
	Public xyzSkipDlgFlag As Int32 = 0
	Public xyzScanFlag As Int32 = 0
	Public xyzBinaryFileFlag As Int32 = 0
	Public xyzMotorolaFlag As Int32 = 0
	Public xyzDoubleFlag As Int32 = 0
	Public xyzRows As Int32 = 0
	Public xyzColumns As Int32 = 0
	Public xyzByColumnFlag As Int32 = 0
	Public xyzClipFlag As Int32 = 0
	Public xyzFromRow As Int32 = 0
	Public xyzToRow As Int32 = 0
	Public xyzFromColumn As Int32 = 0
	Public xyzToColumn As Int32 = 0
	Public xyzAxisFlag As Int32 = 0
	Public xyzSaveDxfFlag As Int32 = 0
	Public xyzDxfReleaseFlag As Int32 = 2
	Public xyzNoDataFlag As Int32 = 0
	Public xyzNoDataValue As Double = -9999.0
	Public xyzNoDataReplaceFlag As Int32 = 0
	Public xyzNoDataReplaceValue As Double = 0.0
	Public xyzScaleZFlag As Int32 = 0
	Public xyzScaleFactorZ As Double = 1.0
	Public xyzHasIdFlag As Int32 = 0
	Public xyzUseIdFlag As Int32 = 0
	' ---
	Public stageImageName As String = Nothing
	Public stageUseFlag As Int32 = 0
	Public stageOriginFlag As Int32 = 0
	Public stageSquaresFlag As Int32 = 0
	Public stageImageFlag As Int32 = 0
	Public stageSpacing As Double = 1.0
	Public stageWidth As Double = 20.0
	Public stageDepth As Double = 20.0
	Public stageOriginX As Double = 0.0
	Public stageOriginY As Double = 0.0
	' ---
	Public reducePolygonsName As String = Nothing
	Public reducePolygonsNextLayer As Int32 = 0
	Public reducePolygonsVertices0 As Int32 = 0
	Public reducePolygonsVertices1 As Int32 = 0
	Public reducePolygonsTriangles0 As Int32 = 0
	Public reducePolygonsTriangles1 As Int32 = 0
	Public reducePolygonsStep As Int32 = 100
	' ---
	Public backgroundImageName As String = Nothing
	Public backgroundImageUseFlag As Int32 = 0
	' ---
	Public bitmapTo3D_SkipDlg_Flag As Int32 = 0
	Public bitmapTo3D_Decode0_Flag As Int32 = 0
	Public bitmapTo3D_SaveOutlines_Flag As Int32 = 0
	Public bitmapTo3D_JoinOutlines_Flag As Int32 = 1
	Public bitmapTo3D_AddFaces_Flag As Int32 = 1
	Public bitmapTo3D_Extrude_Flag As Int32 = 1
	Public bitmapTo3D_ExtrudeHeight As Double = 10.0
	' ---
	Public bitmapToDem_SkipDlg_Flag As Int32 = 0
	Public bitmapToDem_SeaLevel_Flag As Int32 = 0
	Public bitmapToDem_BelowMultiplier As Double = 1.0
	Public bitmapToDem_AboveMultiplier As Double = 10.0
	Public bitmapToDem_MinHeight As Double = 0.0
	Public bitmapToDem_XY_Spacing As Double = 30.0
	' ---
	Public modoCameraSunlightFlag As Int32 = 1
	Public modoHierarchyFlag As Int32 = 0
	Public modoWithJointsFlag As Int32 = 0
	' ---
	Public layerMinMaxName(LEN_LAYER_NAME - 1) As Byte
	Public layerMinMaxNextLayer As Int32 = 0
	' ---
	Public oglGlobalAmbient As RGBA
	Public oglDirectionalLights(OGL_LIGHT_COUNT - 1) As OGL_LIGHT
	Public oglSelectedLight As Int32 = 0
	' ---	
	Public kmlAltitudeModeLabels(At3d_Kml.KML_ALTITUDE_MODE_COUNT - 1) As String

	Public kmlModel_Altitude_Mode_Flag As Int32 = At3d_Kml.KML_RELATIVE_TO_GROUND
	Public kmlLookAt_Altitude_Mode_Flag As Int32 = At3d_Kml.KML_RELATIVE_TO_GROUND

	Public kmlModel_Latitude_Degrees As Int32 = 0
	Public kmlModel_Latitude_Minutes As Int32 = 0
	Public kmlModel_Latitude_Seconds As Double = 0.0
	Public kmlModel_Latitude_Sign As Int32 = 0
	Public kmlModel_Longitude_Degrees As Int32 = 0
	Public kmlModel_Longitude_Minutes As Int32 = 0
	Public kmlModel_Longitude_Seconds As Double = 0.0
	Public kmlModel_Longitude_Sign As Int32 = 0
	Public kmlModel_Altitude As Double = 0.0
	Public kmlModel_Heading As Double = 0.0
	Public kmlModel_Tilt As Double = 0.0
  Public kmlModel_Roll As Double = 0.0
  Public kmlModel_Scale_X As Double = 1.0
  Public kmlModel_Scale_Y As Double = 1.0
  Public kmlModel_Scale_Z As Double = 1.0

	Public kmlLookAt_Latitude_Degrees As Int32 = 0
	Public kmlLookAt_Latitude_Minutes As Int32 = 0
	Public kmlLookAt_Latitude_Seconds As Double = 0.0
	Public kmlLookAt_Latitude_Sign As Int32 = 0
	Public kmlLookAt_Longitude_Degrees As Int32 = 0
	Public kmlLookAt_Longitude_Minutes As Int32 = 0
	Public kmlLookAt_Longitude_Seconds As Double = 0.0
	Public kmlLookAt_Longitude_Sign As Int32 = 0
	Public kmlLookAt_Altitude As Double = 0.0
	Public kmlLookAt_Heading As Double = 0.0
	Public kmlLookAt_Tilt As Double = 0.0
	Public kmlLookAt_Range As Double = 0.0

	Public kmlFolderName As String = Nothing
	Public kmlFolderDescription As String = Nothing
	Public kmlPlacemarkName As String = "Model"
	Public kmlPlacemarkDescription As String = Nothing

	Const LEN_FILE_FNAME As Int32 = 200
	Public kmlModelsFolderName As String = "Models"
	Public kmlImagesFolderName As String = "Images"
	Public kmlUseModelsFolderFlag As Int32 = 1
  Public kmlUseImagesFolderFlag As Int32 = 1
  ' ---
  Public colladaOutputUpAxisFlag As Int32 = 1
	' ---
	Public grabKeyboardFocusFlag As Int32 = 0
  Public alwaysShowCameraCursorFlag As Int32 = 0
  Public debugStopMessagesFlag As Int32 = 0
  ' ---
  Public checkFixTransparenciesFlag As Int32 = 1
  Public kmzInputModelFactorsFlag As Int32 = 0
  Public alwaysWriteColladaTransparencyFlag As Int32 = 0
  ' ---
  Public mayaVersion As String = "6.0"
  Public directxFramePrefix As String = "Frame_"
  Public directxMaterialPrefix As String = "Mat_"

  Public useDirectxFramePrefixFlag As Int32 = 1
  Public useDirectxMaterialPrefixFlag As Int32 = 1


	Public Sub New()
		Dim i As Integer = 0

		inType(i) = At3d_InType.INTYPE_3DMF
		inLabel(i) = "3D Metafile"
		inExt(i) = ".3dm;*.3dmf"
		i += 1

		inType(i) = At3d_InType.INTYPE_3DSTUDIO
		inLabel(i) = "3D Studio"
		inExt(i) = ".3ds;*.asc;*.prj"
		i += 1

		inType(i) = At3d_InType.INTYPE_ARCINFO_ASCII
		inLabel(i) = "ArcInfo ASCII Grid"
		inExt(i) = ".asc"
		i += 1

		inType(i) = At3d_InType.INTYPE_ASCII_DEM
		inLabel(i) = "ASCII DEM"
		inExt(i) = ".txt"
		i += 1

		inType(i) = At3d_InType.INTYPE_BINARY_DEM
		inLabel(i) = "Binary DEM"
		inExt(i) = ".bin"
		i += 1

		inType(i) = At3d_InType.INTYPE_BMP
		inLabel(i) = "Bitmap To 3D"
		inExt(i) = ".bmp;*.gif;*.iff;*.jpg;*.png;*.tga;*.tif"
		i += 1

		inType(i) = At3d_InType.INTYPE_BMP_DEM
		inLabel(i) = "Bitmap To DEM"
		inExt(i) = ".bmp;*.gif;*.iff;*.jpg;*.png;*.tga;*.tif"
		i += 1

		inType(i) = At3d_InType.INTYPE_CABLEMOD
		inLabel(i) = "CableMod"
		inExt(i) = ".xml"
		i += 1


		inType(i) = At3d_InType.INTYPE_CDED
		inLabel(i) = "CDED"
		inExt(i) = ".dem"
		i += 1

    inType(i) = At3d_InType.INTYPE_COLLADA
    inLabel(i) = "Collada"
    inExt(i) = ".dae"
    i += 1

		' may be added in the future
		'
		'inType(i) = At3d_InType.INTYPE_DIRECTX
		'inLabel(i) = "DirectX"
		'inExt(i) = ".x"
		'i += 1

		inType(i) = At3d_InType.INTYPE_DXF
		inLabel(i) = "DXF"
		inExt(i) = ".dxf"
		i += 1

		inType(i) = At3d_InType.INTYPE_DXF_POINTCLOUD
		inLabel(i) = "_DXF Point Cloud"
		inExt(i) = ".dxf"
		i += 1

		inType(i) = At3d_InType.INTYPE_IFF
		inLabel(i) = "IFF To 3D"
		inExt(i) = ".iff"
		i += 1

		inType(i) = At3d_InType.INTYPE_IFF_DEM
		inLabel(i) = "IFF To DEM"
		inExt(i) = ".iff"
		i += 1

    inType(i) = At3d_InType.INTYPE_GOOGLE_EARTH
    inLabel(i) = "Google Earth KMZ"
    inExt(i) = ".kmz"
    i += 1

		inType(i) = At3d_InType.INTYPE_IMAGINE
    inLabel(i) = "Imagine / Turbo Silver 3.0"
		inExt(i) = ".iob"
		i += 1

		' may be added in the future
		'
		'inType(i) = At3d_InType.INTYPE_KERKYTHEA
		'inLabel(i) = "Kerkythea"
		'inExt(i) = ".xml"
		'i += 1

		inType(i) = At3d_InType.INTYPE_LIGHTSCAPE
		inLabel(i) = "Lightscape"
		inExt(i) = ".lp"
		i += 1

		inType(i) = At3d_InType.INTYPE_LIGHTWAVE
		inLabel(i) = "LightWave"
		inExt(i) = ".lwo"
		i += 1

		inType(i) = At3d_InType.INTYPE_MAYA_RTG
		inLabel(i) = "Maya RTG"
		inExt(i) = ".rtg"
		i += 1

		inType(i) = At3d_InType.INTYPE_MAXNC
		inLabel(i) = "MaxNC Digital Probe"
		inExt(i) = ".txt"
		i += 1

		inType(i) = At3d_InType.INTYPE_MICRODEM
		inLabel(i) = "MicroDEM"
		inExt(i) = ".dem"
		i += 1

		inType(i) = At3d_InType.INTYPE_MODO
		inLabel(i) = "modo"
		inExt(i) = ".lxo"
		i += 1

		inType(i) = At3d_InType.INTYPE_NASTRAN
		inLabel(i) = "NASTRAN"
		inExt(i) = ".bdf"
		i += 1

		' may be added in the future
		'
		'inType(i) = At3d_InType.INTYPE_OPEN_INVENTOR
		'inLabel(i) = "Open Inventor"
		'inExt(i) = ".iv"
		'i += 1

		inType(i) = At3d_InType.INTYPE_REALIMATION
		inLabel(i) = "RealiMation"
		inExt(i) = ".rbs"
		i += 1

		inType(i) = At3d_InType.INTYPE_RENDERWARE
		inLabel(i) = "RenderWare"
		inExt(i) = ".rwx"
		i += 1

		inType(i) = At3d_InType.INTYPE_SATELLITE_TOOLKIT
		inLabel(i) = "Satellite Tool Kit"
		inExt(i) = ".mdl"
		i += 1

		inType(i) = At3d_InType.INTYPE_SCENERY_ANIMATOR
		inLabel(i) = "Scenery Animator"
		inExt(i) = ".land"
		i += 1

		inType(i) = At3d_InType.INTYPE_SCULPT
		inLabel(i) = "Sculpt"
		inExt(i) = ".scene"
		i += 1

		inType(i) = At3d_InType.INTYPE_SHOPBOT
		inLabel(i) = "ShopBot Digital Probe"
		inExt(i) = ".sbp"
		i += 1

		' may be added in the future
		'
		'inType(i) = At3d_InType.INTYPE_SOFTIMAGE_XSI
		'inLabel(i) = "Softimage!XSI"
		'inExt(i) = ".xsi"
		'i += 1

		inType(i) = At3d_InType.INTYPE_STEREOLITHOGRAPHY
		inLabel(i) = "StereoLithography"
		inExt(i) = ".stl"
		i += 1

		inType(i) = At3d_InType.INTYPE_TECPLOT
		inLabel(i) = "Techplot"
		inExt(i) = ".dat"
		i += 1

		inType(i) = At3d_InType.INTYPE_TRUESPACE
		inLabel(i) = "trueSpace"
		inExt(i) = ".cob;*.coa"
		i += 1

		inType(i) = At3d_InType.INTYPE_USGS_GTOPO30
		inLabel(i) = "USGS GTOPO30/SRTM30"
		inExt(i) = ".dem"
		i += 1

		inType(i) = At3d_InType.INTYPE_USGS_DEM
		inLabel(i) = "USGS 1 degree DEM"
		inExt(i) = ".dem"
		i += 1

		inType(i) = At3d_InType.INTYPE_USGS_SDTS
		inLabel(i) = "USGS SDTS"
		inExt(i) = "catd.ddf"
		i += 1

		inType(i) = At3d_InType.INTYPE_USGS_SRTM_1_3
		inLabel(i) = "USGS SRTM-1/SRTM-3"
		inExt(i) = "*.hgt"
		i += 1

		inType(i) = At3d_InType.INTYPE_VIDEOSCAPE
		inLabel(i) = "VideoScape"
		inExt(i) = ".geo"
		i += 1

		inType(i) = At3d_InType.INTYPE_VISTAPRO
		inLabel(i) = "VistaPro"
		inExt(i) = ".dem"
		i += 1

		inType(i) = At3d_InType.INTYPE_VRML
		inLabel(i) = "VRML"
		inExt(i) = ".wrl"
		i += 1

		inType(i) = At3d_InType.INTYPE_WAVEFRONT
		inLabel(i) = "Wavefront"
		inExt(i) = ".obj"
		i += 1

		' may be added in the future
		'
		'inType(i) = At3d_InType.INTYPE_X3D
		'inLabel(i) = "X3D"
		'inExt(i) = ".x3d"
		'i += 1

		inType(i) = At3d_InType.INTYPE_XGL
		inLabel(i) = "XGL, ZGL"
		inExt(i) = ".xgl;*.zgl"
		i += 1

		inType(i) = At3d_InType.INTYPE_XYZ
		inLabel(i) = "XYZ"
		inExt(i) = ".xyz"
		i += 1

		inType(i) = At3d_InType.INTYPE_XYZ_NO_MESH
		inLabel(i) = "XYZ (No Mesh)"
		inExt(i) = ".xyz"
		i += 1

		inCount = i
    inIndex = 17

		' ---
		i = 0

		outType(i) = At3d_OutType.OUTTYPE_3DMETAFILE_ASCII
		outLabel(i) = "3D Metafile (ASCII)"
		outExt(i) = ".3dmf"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_3DMETAFILE_BINARY
		outLabel(i) = "3D Metafile (Binary)"
		outExt(i) = ".3dmf"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_3DSTUDIO_ASCII
		outLabel(i) = "3D Studio (ASCII)"
		outExt(i) = ".asc"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_3DSTUDIO_BINARY
		outLabel(i) = "3D Studio (Binary)"
		outExt(i) = ".3ds"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_ARCINFO_ASCII
		outLabel(i) = "ArcInfo ASCII Grid"
		outExt(i) = ".asc"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_BINARY_DEM
		outLabel(i) = "Binary DEM"
		outExt(i) = ".bin"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_BMP
		outLabel(i) = "Bitmap"
		outExt(i) = ".png"		 ' extension can be bmp, jpg or png
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_DEM_CONTOUR_LINES
		outLabel(i) = "DEM Contour Lines"
		outExt(i) = ".dxf"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_DEM_CONTOUR_MAP
		outLabel(i) = "DEM Contour Map"
		outExt(i) = ".bmp"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_CABLEMOD
		outLabel(i) = "CableMod"
		outExt(i) = ".xml"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_COLLADA
		outLabel(i) = "Collada"
		outExt(i) = ".dae"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_DIRECTX_ASCII
		outLabel(i) = "DirectX (ASCII)"
		outExt(i) = ".x"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_DIRECTX_BINARY
		outLabel(i) = "DirectX (Binary)"
		outExt(i) = ".x"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_DXF
		outLabel(i) = "DXF"
		outExt(i) = ".dxf"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_GOOGLE_EARTH
        outLabel(i) = "Google Earth KMZ"
		outExt(i) = ".kmz"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_IMAGINE1
		outLabel(i) = "Imagine (original)"
		outExt(i) = ".iob"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_IMAGINE2
		outLabel(i) = "Imagine (huge objects)"
		outExt(i) = ".iob"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_KERKYTHEA
		outLabel(i) = "Kerkythea"
		outExt(i) = ".xml"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_LIGHTSCAPE
		outLabel(i) = "Lightscape"
		outExt(i) = ".lp"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_LIGHTWAVE1
		outLabel(i) = "LightWave (original)"
		outExt(i) = ".lwo"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_LIGHTWAVE2
		outLabel(i) = "LightWave (huge objects)"
		outExt(i) = ".lwo"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_MAYA_MA
		outLabel(i) = "Maya MA"
		outExt(i) = ".ma"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_MODO
		outLabel(i) = "modo"
		outExt(i) = ".lxo"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_OPEN_INVENTOR
		outLabel(i) = "Open Inventor"
		outExt(i) = ".iv"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_POVRAY
		outLabel(i) = "POVRay"
		outExt(i) = ".pov"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_REALIMATION
		outLabel(i) = "RealiMation"
		outExt(i) = ".rbs"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_RENDERWARE
		outLabel(i) = "RenderWare"
		outExt(i) = ".rwx"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_SATELLITE_TOOLKIT
		outLabel(i) = "Satellite Tool Kit"
		outExt(i) = ".mdl"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_SCENERY_ANIMATOR
		outLabel(i) = "Scenery Animator"
		outExt(i) = ".land"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_SCULPT
		outLabel(i) = "Sculpt"
		outExt(i) = ".scene"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_SOFTIMAGE_XSI_ASCII
		outLabel(i) = "Softimage!XSI (ASCII)"
		outExt(i) = ".xsi"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_STL_ASCII
		outLabel(i) = "StereoLithography (ASCII)"
		outExt(i) = ".stl"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_STL_BINARY
		outLabel(i) = "StereoLithography (Binary)"
		outExt(i) = ".stl"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_TRUESPACE_ASCII
		outLabel(i) = "trueSpace (ASCII)"
		outExt(i) = ".coa"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_TRUESPACE_BINARY
		outLabel(i) = "trueSpace (Binary)"
		outExt(i) = ".cob"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_TURBOSILVER
		outLabel(i) = "TurboSilver"
		outExt(i) = ".iob"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_VIDEOSCAPE
		outLabel(i) = "VideoScape"
		outExt(i) = ".geo"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_VIEWPOINT
		outLabel(i) = "Viewpoint Scene"
		outExt(i) = ".mtx"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_VISTAPRO
		outLabel(i) = "VistaPro"
		outExt(i) = ".dem"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_VRML1
		outLabel(i) = "VRML 1"
		outExt(i) = ".wrl"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_VRML2
		outLabel(i) = "VRML 2"
		outExt(i) = ".wrl"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_WAVEFRONT
		outLabel(i) = "Wavefront"
		outExt(i) = ".obj"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_X3D
		outLabel(i) = "X3D"
		outExt(i) = ".x3d"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_XGL
		outLabel(i) = "XGL"
		outExt(i) = ".xgl"
		i += 1

		outType(i) = At3d_OutType.OUTTYPE_ZGL
		outLabel(i) = "ZGL"
		outExt(i) = ".zgl"
		i += 1

		outCount = i
		outIndex = 19

		' ---
		i = 0

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_POINTCLOUD
		oglRenderLabel(i) = "Point cloud"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_BOUNDINGBOX
		oglRenderLabel(i) = "Bounding boxes"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_WIREFRAME_ONECOLOR
		oglRenderLabel(i) = "One Color wireframe"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_HIDDEN_WIREFRAME_ONECOLOR
		oglRenderLabel(i) = "One Color hidden wireframe"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_WIREFRAME_MULTICOLOR
		oglRenderLabel(i) = "Multi color wireframe"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_HIDDEN_WIREFRAME_MULTICOLOR
		oglRenderLabel(i) = "Multi color hidden wireframe"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_FLAT
		oglRenderLabel(i) = "Flat shading"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_SMOOTH
		oglRenderLabel(i) = "Smooth shading"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_FLAT_EDGE
		oglRenderLabel(i) = "Flat shading with edge"
		i += 1

		oglRenderType(i) = At3d_OglRender.OGL_RENDER_SMOOTH_EDGE
		oglRenderLabel(i) = "Smooth shading with edge"
		i += 1

		oglRenderCount = i
		oglRenderIndex = 7

		' ---
		i = 0

		backgroundType(i) = At3d_CMap.CMAP_DXF_PEN_0
		backgroundLabel(i) = "DXF Drawings"
		i += 1

		backgroundType(i) = At3d_CMap.CMAP_COLOR_BACKGROUND
		backgroundLabel(i) = "Color Shades"
		i += 1

		backgroundType(i) = At3d_CMap.CMAP_GREY_BACKGROUND
		backgroundLabel(i) = "Grey Shades"
		i += 1

		backgroundType(i) = At3d_CMap.CMAP_OGL_BACKGROUND
		backgroundLabel(i) = "OpenGL"
		i += 1

		backgroundType(i) = At3d_DemCMap.DEM_CMAP_BACKGROUND
		backgroundLabel(i) = "Landscapes"
		i += 1

		backgroundCount = i
		backgroundIndex = 3

		backgroundColor.red = 0.58
		backgroundColor.green = 0.68
		backgroundColor.blue = 0.85

		' ---
		i = 0

		textureType(i) = At3d_TextureMapType.TEXTUREMAP_PLANAR
		textureTypeLabel(i) = "Planar"
		i += 1

		textureType(i) = At3d_TextureMapType.TEXTUREMAP_CYLINDRICAL
		textureTypeLabel(i) = "Cylindrical"
		i += 1

		textureType(i) = At3d_TextureMapType.TEXTUREMAP_SPHERICAL
		textureTypeLabel(i) = "Spherical"
		i += 1

		textureTypeCount = i
		textureTypeIndex = 0

		textureScale(0) = 1.0
		textureScale(1) = 1.0

		meshToLandscape.xSpacing = 10.0
		meshToLandscape.ySpacing = 10.0

		meshToLandscape.dropElevation = 0.0
		meshToLandscape.baseThickness = 1.0

		kmlAltitudeModeLabels(At3d_Kml.KML_CLAMP_TO_GROUND) = "clampToGround"
		kmlAltitudeModeLabels(At3d_Kml.KML_RELATIVE_TO_GROUND) = "relativeToGround"
		kmlAltitudeModeLabels(At3d_Kml.KML_ABSOLUTE) = "absolute"
		kmlAltitudeModeLabels(At3d_Kml.KML_RELATIVE_TO_SEA_FLOOR) = "relativeToSeaFloor"
		kmlAltitudeModeLabels(At3d_Kml.KML_CLAMP_TO_SEA_FLOOR) = "clampToSeaFloor"
	End Sub


	Public Sub Clear_All_Objects()
		' clear or delete all 3D, 2D and Point Cloud objects
		'
		At3d_Clear()
		fileLoaded = 0

		' also set any values in application that are affected
		'
		extrudeModeFlag = 0
		bevelSetsFlag = 0

		textName(0) = 0
		textNextLayer = 0

		editName(0) = 0
		editNextLayer = 0

		layerMinMaxName(0) = 0
		layerMinMaxNextLayer = 0
	End Sub

	Public Sub ReadFile()
		Dim scaleFactor As Double = 1.0

		If dllOpen = 0 Then
			bufferReadFlag = 0
			Return
		End If

		Dim path1 As String = "c:\"
		If inName <> Nothing Then
			path1 = Path.GetDirectoryName(inName)
		End If

		readType = inType(inIndex)

		Dim filter As String
		filter = inLabel(inIndex)
		filter += "|*"
		filter += inExt(inIndex)
		filter += "|All|*.*"

		Dim dlg As New OpenFileDialog()

		dlg.InitialDirectory = path1
		dlg.Filter = filter
		dlg.FilterIndex = 1
		dlg.CheckFileExists = True
		dlg.CheckPathExists = True
		dlg.RestoreDirectory = True

		If dlg.ShowDialog() = DialogResult.OK Then
			inName = dlg.FileName

			' before reading make sure flags are set properly
			' (note: flags maintain their setting until changed with this function)
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_REMOVE_DUPLICATE_VERTICES, removeVerticesFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_REMOVE_DUPLICATE_FACES, removeFacesFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SHOW_READ_MESSAGES, showReadMessagesFlag)
      At3d_WriteFlag(At3d_LibFlag.LIBFLAG_VRML_BY_CHIEF_ARCHITECT, vrmlByChiefArchitectFlag)
      At3d_WriteFlag(At3d_LibFlag.LIBFLAG_VRML_MITER_JOINT_EXTRUSION, vrmlMiterJointExtrusionFlag)

			' turn off this flag so texture search prompt message
			' is not displayed when textures are not found
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TEXTURESEARCH_PROMPT, textureSearchFlag)

			Dim fontName(LEN_LAYER_NAME - 1) As Byte

			If readType = At3d_InType.INTYPE_DXF Then
				If useDxfTextFlag > 0 And dxfFontName <> Nothing Then
					fontName = AE.GetBytes(dxfFontName)
					At3d_SetDxfFontName(fontName(0))
				End If

				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_USE_DXF_TEXT, useDxfTextFlag)
			End If

            ' if set, after read invert transparencies if all layers are transparent
            '
            At3d_WriteFlag(At3d_LibFlag.LIBFLAG_CHECK_AND_FIX_TRANSPARENCIES, checkFixTransparenciesFlag)

            ' if set, after reading KMZ file apply the KMZ model factors
            '
            At3d_WriteFlag(At3d_LibFlag.LIBFLAG_KMZ_INPUT_MODEL_FACTORS, kmzInputModelFactorsFlag)

			If readType = At3d_InType.INTYPE_VRML Then
				If vrmlTextFlag Then
					fontName = AE.GetBytes(vrmlSerifFontName)
					At3d_SetVrmlSerifFontName(fontName(0))

					fontName = AE.GetBytes(vrmlSansFontName)
					At3d_SetVrmlSansFontName(fontName(0))

					fontName = AE.GetBytes(vrmlTypewriterFontName)
					At3d_SetVrmlTypewriterFontName(fontName(0))
				End If

				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_VRML_TEXT_TO_3D, vrmlTextFlag)
			End If

			' used when the 'Open XYZ File' dialog box is being bypassed
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_SKIP_DLG, xyzSkipDlgFlag)

			Dim doFlagXYZ As Integer = 0
			If readType = At3d_InType.INTYPE_XYZ Then doFlagXYZ = 1
			If readType = At3d_InType.INTYPE_XYZ_NO_MESH Then doFlagXYZ = 1

			If xyzSkipDlgFlag And doFlagXYZ Then
				' set delimiters
				'
				Dim delimiters As Byte() = AE.GetBytes(xyzDelimiters)
				At3d_XYZ_SetDelimiters(delimiters(0))

				' set axis system
				'
				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_AXIS, xyzAxisFlag)

				' set XYZ Type for Mesh or Scan
				'
				If readType = At3d_InType.INTYPE_XYZ Then
					At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_SCAN, xyzScanFlag)
				End If

				' set for ASCII or Binary file type
				'
				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_BINARY_FILE, xyzBinaryFileFlag)

				If xyzBinaryFileFlag Then
					' set Byte Order and Floating Point Type
					'
					At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_MOTOROLA, xyzMotorolaFlag)
					At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_DOUBLE, xyzDoubleFlag)
				Else
					' ID only used with point cloud
					'
					If readType = At3d_InType.INTYPE_XYZ_NO_MESH Then
						At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_HAS_ID, xyzHasIdFlag)
						At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_USE_ID, xyzUseIdFlag)
					End If
				End If

				' when XYZ Type is Mesh
				'
				If xyzScanFlag = 0 And readType = At3d_InType.INTYPE_XYZ Then
					' set number of rows and columns
					'
					At3d_XYZ_SetRowsColumns(xyzRows, xyzColumns)

					' set data stored as By Row or By Column
					'
					At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_BY_COLUMN, xyzByColumnFlag)

					If bufferReadFlag Then
						At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_SAVE_DXF, 0)
					Else
						At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_SAVE_DXF, xyzSaveDxfFlag)
						If xyzSaveDxfFlag Then
							Dim xyzDxfName As String
							xyzDxfName = Path.ChangeExtension(inName, ".dxf")
							Dim xyzDxfFileName As Byte() = AE.GetBytes(xyzDxfName)
							At3d_XYZ_SetDxfOutFile(xyzDxfFileName(0), 1.0)

							At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_DXF_RELEASE, xyzDxfReleaseFlag)
						End If
					End If

					At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_CLIP, xyzClipFlag)
					If xyzClipFlag Then
						At3d_XYZ_SetClipRectangle(xyzFromRow, xyzToRow, xyzFromColumn, xyzToColumn)
					End If
				End If

                ' when XYZ Type is Probe Scan or Double Z Scan
				'
				If xyzScanFlag And readType = At3d_InType.INTYPE_XYZ Then
					At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_SCALE_Z, xyzScaleZFlag)
					If xyzScaleZFlag Then
						At3d_XYZ_SetScaleFactorZ(xyzScaleFactorZ)
					End If

          If xyzScanFlag = 1 Then
            At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_NODATA, xyzNoDataFlag)
            If xyzNoDataFlag Then
              At3d_XYZ_SetNoDataValue(xyzNoDataValue)

              At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_NODATA_REPLACE, xyzNoDataReplaceFlag)

              At3d_XYZ_SetNoDataReplaceValue(xyzNoDataReplaceValue)
            End If
          Else
            At3d_WriteFlag(At3d_LibFlag.LIBFLAG_XYZ_NODATA, 0)
          End If
        End If
      End If


      ' used when the 'Convert Bitmap To 3D' dialog box is being bypassed
      '
      At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_3D_SKIP_DLG, bitmapTo3D_SkipDlg_Flag)

      Dim doFlagBitmapTo3D As Integer = 0
      If readType = At3d_InType.INTYPE_BMP Then doFlagBitmapTo3D = 1
      If readType = At3d_InType.INTYPE_IFF Then doFlagBitmapTo3D = 1

      If bitmapTo3D_SkipDlg_Flag And doFlagBitmapTo3D Then
        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_3D_DECODE_0, bitmapTo3D_Decode0_Flag)

        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_3D_SAVE_OUTLINES, bitmapTo3D_SaveOutlines_Flag)

        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_3D_JOIN_OUTLINES, bitmapTo3D_JoinOutlines_Flag)

        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_3D_ADD_FACES, bitmapTo3D_AddFaces_Flag)

        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_3D_EXTRUDE, bitmapTo3D_Extrude_Flag)

        At3d_SetBitmapTo3D_ExtrudeHeight(bitmapTo3D_ExtrudeHeight)
      End If


      ' used when the 'Convert Contour Map' dialog box is being bypassed
      '
      At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_LANDSCAPE_SKIP_DLG, bitmapToDem_SkipDlg_Flag)

      Dim doFlagBitmapToDem As Integer = 0
      If readType = At3d_InType.INTYPE_BMP_DEM Then doFlagBitmapToDem = 1
      If readType = At3d_InType.INTYPE_IFF_DEM Then doFlagBitmapToDem = 1

      If bitmapToDem_SkipDlg_Flag And doFlagBitmapToDem Then
        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_BITMAP_TO_LANDSCAPE_SEA_LEVEL, bitmapToDem_SeaLevel_Flag)

        At3d_SetBitmapToLandscapeValues(bitmapToDem_BelowMultiplier, bitmapToDem_AboveMultiplier, bitmapToDem_MinHeight, bitmapToDem_XY_Spacing)
      End If


      If bufferReadFlag Then
        Dim fi As FileInfo = New FileInfo(inName)
        Dim buffer(fi.Length - 1) As Byte

        Dim stream As FileStream = New FileStream(inName, FileMode.Open, FileAccess.Read, FileShare.Read)
        Dim reader As BinaryReader = New BinaryReader(stream)
        reader.Read(buffer, 0, fi.Length)
        reader.Close()
        stream.Close()

        fileLoaded = At3d_BufferRead(readType, scaleFactor, buffer(0), fi.Length)
      Else
        Dim name1 As Byte() = AE.GetBytes(inName)
        fileLoaded = At3d_Read(readType, name1(0), scaleFactor)
      End If
    End If

    bufferReadFlag = 0
	End Sub


	Public Sub ReadAndRotateFile()
		' Three different coordinate systems are used by 3D model making software
		'
		' A 3D object may be written to a file format with the wrong coordinate system
		'
		' This can be corrected after reading the file
		'
		' This example shows rotating from a Right Hand System to a CAD Right Hand System
		'
		' turn off drawing to the view window
		' so the user does not see the object being rotated
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 1)

		' read the file as though the user had clicked the 'Read' button on the 'Read' page
		'
		ReadFile()

		If fileLoaded Then
			' Set flag to rotate about the origin
			' When switching from one axis coordinate system to another
			' the rotation should be around the origin so that the coordinate
			' values do not change and only move from axis to another
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_ORIGIN_ROTATE, 1)

			' Rotate the object -90 degrees around the X axis
			'
			At3d_RotateObjectX_90Minus()

			' Reset the camera for the above rotation changes
			'
			At3d_ZoomReset()

			' Set flag to rotate about the mid point of the object
			' which is the default
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_ORIGIN_ROTATE, 0)
		End If

		' Turn on drawing to the view window
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)

		' Draw the object to the view window
		'
		If fileLoaded Then
			At3d_DrawWireframe()
		End If

	End Sub


	Public Sub WriteFile()
		If fileLoaded = 0 Then
			bufferWriteFlag = 0
			Return
		End If

		' if there is no file name, such as when creating
		' a 3D mesh from a TrueType font, create a dummy name
		'
		If inName = Nothing Then
			inName = "noname.lwo"
		End If

		Dim scaleFactor As Double = 1.0

		' get name
		'
		Dim name As String
		name = Path.GetFileNameWithoutExtension(inName)

		' get drive and dir
		'
		Dim path1 As String
		If outName = Nothing Then
			path1 = Path.GetDirectoryName(inName)
		Else
			path1 = Path.GetDirectoryName(outName)
		End If

		' construct output file name
		'
		name += outExt(outIndex)

		writeType = outType(outIndex)

		Dim filter As String = outLabel(outIndex)
		filter += "|*"
		filter += outExt(outIndex)

		Dim dlg As New SaveFileDialog()

		dlg.InitialDirectory = path1
		dlg.Filter = filter
		dlg.FilterIndex = 1
		dlg.FileName = name
		dlg.CheckPathExists = True
		dlg.OverwritePrompt = True
		dlg.RestoreDirectory = True

		If dlg.ShowDialog() = DialogResult.OK Then
			outName = dlg.FileName

			' before writing file make sure all flags are set properly
			' (note: flags maintain their setting until changed with this function)
			' Example: UV ouput flag default is on
			' test app shows default UV as off so setting flag
			' to agree with screen display
			'
            At3d_WriteFlag(At3d_LibFlag.LIBFLAG_AVATAR_OUTPUT, outputAvatarFlag)
            At3d_WriteFlag(At3d_LibFlag.LIBFLAG_HIERARCHY_OUTPUT, outputHierarchyFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_WRITE_ONE_LAYER_PER_FILE, oneLayerPerFileFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_ONEOBJECT_MULTIMATERIAL, multiMaterialFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_USE_QUADFACE, quadFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_UV_OUTPUT, uvFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_VERTNORM_OUTPUT, vnormFlag)
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_VCOLOR_OUTPUT, vcolorFlag)

			' discontinued at version 1.3.1
			'
			'At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SHOW_SAVE_MESSAGES, showSaveMessagesFlag)

			' The material MTL file is written at
			' the same time as the Wavefront OBJ file
			' flag only has to be set now if it has not been set before
			'
			If writeType = At3d_OutType.OUTTYPE_WAVEFRONT Then
				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_MTL_FILE, 1)
			End If

			' set type of object to write to 3DMF file
			'
			Dim doFlag3dmf As Integer = 0
			If writeType = At3d_OutType.OUTTYPE_3DMETAFILE_ASCII Then doFlag3dmf = 1
			If writeType = At3d_OutType.OUTTYPE_3DMETAFILE_BINARY Then doFlag3dmf = 1

			If doFlag3dmf = 1 Then
				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_3DMF_TYPE, outType3dmf)
				At3d_WriteFlag(At3d_LibFlag.LIBFLAG_PIXEL_SIZE_3DMF, pixelFlag3dmf)
			End If

      ' set output parameters for Collada DAE file
      '
      If writeType = At3d_OutType.OUTTYPE_COLLADA Then
        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_ALWAYS_WRITE_COLLADA_TRANSPARENCY, alwaysWriteColladaTransparencyFlag)

        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_COLLADA_OUTPUT_UP_AXIS, colladaOutputUpAxisFlag)
      End If

			' set output parameters for KML file for Google Earth
			'
			If writeType = At3d_OutType.OUTTYPE_GOOGLE_EARTH Then
        Dim nameFolder As Byte()
        Dim nameDescription1 As Byte()

        If kmlFolderName = Nothing Then
          ' to prevent null pointer warning set string to "null"
          ' and DLL will treat this string as a null pointer
          '
          nameFolder = AE.GetBytes("null")
        Else
          nameFolder = AE.GetBytes(kmlFolderName)
        End If

        If kmlFolderDescription = Nothing Then
          ' to prevent null pointer warning set string to "null"
          ' and DLL will treat this string as a null pointer
          '
          nameDescription1 = AE.GetBytes("null")
        Else
          nameDescription1 = AE.GetBytes(kmlFolderDescription)
        End If

				At3d_Set_KML_Folder(nameFolder(0), nameDescription1(0))

        Dim namePlacemark As Byte()
        Dim nameDescription2 As Byte()

        If kmlPlacemarkName = Nothing Then
          ' to prevent null pointer warning set string to "null"
          ' and DLL will treat this string as a null pointer
          '
          namePlacemark = AE.GetBytes("null")
        Else
          namePlacemark = AE.GetBytes(kmlPlacemarkName)
        End If

        If kmlPlacemarkDescription = Nothing Then
          ' to prevent null pointer warning set string to "null"
          ' and DLL will treat this string as a null pointer
          '
          nameDescription2 = AE.GetBytes("null")
        Else
          nameDescription2 = AE.GetBytes(kmlPlacemarkDescription)
        End If

				At3d_Set_KML_Placemark(namePlacemark(0), nameDescription2(0))

				Dim kmlLookAt_Latitude As Double = Combine_DMS(kmlLookAt_Latitude_Degrees, kmlLookAt_Latitude_Minutes, kmlLookAt_Latitude_Seconds, kmlLookAt_Latitude_Sign)
				Dim kmlLookAt_Longitude As Double = Combine_DMS(kmlLookAt_Longitude_Degrees, kmlLookAt_Longitude_Minutes, kmlLookAt_Longitude_Seconds, kmlLookAt_Longitude_Sign)

				At3d_Set_KML_LookAt(kmlLookAt_Latitude, kmlLookAt_Longitude, kmlLookAt_Altitude, kmlLookAt_Altitude_Mode_Flag, kmlLookAt_Heading, kmlLookAt_Tilt, kmlLookAt_Range)

				Dim kmlModel_Latitude As Double = Combine_DMS(kmlModel_Latitude_Degrees, kmlModel_Latitude_Minutes, kmlModel_Latitude_Seconds, kmlModel_Latitude_Sign)
				Dim kmlModel_Longitude As Double = Combine_DMS(kmlModel_Longitude_Degrees, kmlModel_Longitude_Minutes, kmlModel_Longitude_Seconds, kmlModel_Longitude_Sign)

        At3d_Set_KML_ModelEx(kmlModel_Latitude, kmlModel_Longitude, kmlModel_Altitude, kmlModel_Altitude_Mode_Flag, kmlModel_Heading, kmlModel_Tilt, kmlModel_Roll, kmlModel_Scale_X, kmlModel_Scale_Y, kmlModel_Scale_Z)

        Dim nameModelsFolder As Byte()
        Dim nameImagesFolder As Byte()

        If kmlModelsFolderName = Nothing Then
          ' to prevent null pointer warning set string to "null"
          ' and DLL will treat this string as a null pointer
          '
          nameModelsFolder = AE.GetBytes("null")
        Else
          nameModelsFolder = AE.GetBytes(kmlModelsFolderName)
        End If

        If kmlImagesFolderName = Nothing Then
          ' to prevent null pointer warning set string to "null"
          ' and DLL will treat this string as a null pointer
          '
          nameImagesFolder = AE.GetBytes("null")
        Else
          nameImagesFolder = AE.GetBytes(kmlImagesFolderName)
        End If

        At3d_Set_KML_ModelImage_Folders(kmlUseModelsFolderFlag, nameModelsFolder(0), kmlUseImagesFolderFlag, nameImagesFolder(0))
      End If

      ' set output parameters for modo LXO files
      '
      If writeType = At3d_OutType.OUTTYPE_MODO Then
        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_LXO_CAMERA_LIGHT, modoCameraSunlightFlag)
        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_LXO_HIERARCHY, modoHierarchyFlag)
        At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_LXO_JOINTS, modoWithJointsFlag)
      End If

      ' Point clouds are only written if the flag is set
      ' Point clouds can not be written to all file formats
      '
      At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_POINTCLOUD, savePointCloudFlag)

      ' 2D lines are only written if the flag is set
      ' 2D lines can not be written to all file formats
      '
      At3d_WriteFlag(At3d_LibFlag.LIBFLAG_SAVE_2D, save2DFlag)

      If relocateTexturesFlag Then
        ' At3d_Relocate_Textures() function can be used at any time and is only
        ' placed here because a file path is available to use with the function
        '
        ' relocate the textures to the same folder the file will be written to
        ' it is okay if the path contains a file name and extension
        ' if the path does not contain a file name, the path must end with a
        ' slash '\' so that the folder name is not used as a file name
        '
        ' the new texture path will be copied to each layer that uses textures
        '
        ' if overwriteFlag = 2, the new texture name will be copied to the layer
        '
        Dim name2 As Byte() = AE.GetBytes(outName)
        At3d_Relocate_Textures(name2(0), 0, 2)
      End If

      If bufferWriteFlag Then
        Dim bufferSize As Int32

        bufferSize = At3d_PreBufferWrite(writeType)
        If bufferSize = 0 Then
          bufferWriteFlag = 0
          Return
        End If

        ' if writing a Wavefront OBJ and MTL files
        ' check for size of MTL file
        '
        Dim mtlBufferSize As Int32 = 0
        If writeType = At3d_OutType.OUTTYPE_WAVEFRONT Then
          mtlBufferSize = At3d_GetMtlSize()
        End If

        Dim buffer(bufferSize - 1) As Byte
        Dim mtlBuffer() As Byte = Nothing
        Dim mtlSaveFlag As Integer = 0

        If writeType = At3d_OutType.OUTTYPE_WAVEFRONT And mtlBufferSize > 0 Then
          ReDim mtlBuffer(mtlBufferSize)
          At3d_SetMtlBuffer(mtlBuffer(0), mtlBufferSize)

          ' send the name that will be used for the OBJ and MTL file
          '
          Dim buffername As String = Path.GetFileNameWithoutExtension(outName)
          Dim bname() As Byte = AE.GetBytes(buffername)
          At3d_BufferName(bname(0))

          mtlSaveFlag = 1
        End If

        At3d_BufferWrite(writeType, scaleFactor, buffer(0), bufferSize)

        Dim stream As FileStream = New FileStream(outName, FileMode.Create, FileAccess.Write, FileShare.None)
        Dim writer As BinaryWriter = New BinaryWriter(stream)
        writer.Write(buffer, 0, bufferSize)
        writer.Close()
        stream.Close()

        If mtlSaveFlag Then
          Dim mtlName As String = Path.ChangeExtension(outName, ".mtl")
          stream = New FileStream(mtlName, FileMode.Create, FileAccess.Write, FileShare.None)
          writer = New BinaryWriter(stream)
          writer.Write(mtlBuffer, 0, mtlBufferSize)
          writer.Close()
          stream.Close()
        End If
      Else
        Dim name1 As Byte() = AE.GetBytes(outName)
        At3d_Write(writeType, name1(0), scaleFactor)
      End If
    End If

    bufferWriteFlag = 0
	End Sub


	Public Function Transfer_Face_Verts_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim k As Int32
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim decisionFlag As Int32
		If transferFromTypeFlag = At3d_TransferFromFlag.TYPE_BASIC Then
			decisionFlag = 1
		ElseIf transferFromTypeFlag = At3d_TransferFromFlag.TYPE_ARRAYS Then
			decisionFlag = 1
		ElseIf transferFromTypeFlag = At3d_TransferFromFlag.TYPE_XYZ_UV Then
			decisionFlag = 0
		End If

		Dim pcount As Int32
		If decisionFlag Then
			pcount = At3d_VertexCount(name(0))
			If pcount > 0 Then
				dataList(index).PCount3D = pcount

				' the DLL stores the vertices as double
				' the vertices can be transferred as either
				' double or float between the DLL and the application
				'
				If vertexFloatTransferFlag Then
					ReDim dataList(index).xyzFloat3D(pcount - 1)
				Else
					ReDim dataList(index).xyz3D(pcount - 1)
				End If

				Dim fvPtr As Int32 = 0

				If fastFlag Then
					If vertexFloatTransferFlag Then
						fvPtr = At3d_GetAllFloatVertices(name(0), pcount, dataList(index).xyzFloat3D(0).x)
					Else
						fvPtr = At3d_GetAllVertices(name(0), pcount, dataList(index).xyz3D(0).x)
					End If

					If fvPtr = 0 Then
						errorFlag += 1
					End If
				Else
					For k = 0 To pcount - 1
						If vertexFloatTransferFlag Then
							fvPtr = At3d_GetFloatVertex(k, name(0), dataList(index).xyzFloat3D(k).x)
						Else
							fvPtr = At3d_GetVertex(k, name(0), dataList(index).xyz3D(k).x)
						End If

						If fvPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If
			End If
		Else
			pcount = At3d_XYZ_UV_Array_Count(name(0))
			If pcount Then
				dataList(index).xyz_uvCount = pcount

				' the DLL stores the vertices as double
				' the vertices can be transferred as either
				' double or float between the DLL and the application
				'
				If vertexFloatTransferFlag Then
					ReDim dataList(index).xyzFloat_uv(pcount - 1)
				Else
					ReDim dataList(index).xyz_uv(pcount - 1)
				End If

				dataList(index).uvPresentFlag = At3d_UVPresent(name(0))

				Dim fvPtr As Int32 = 0

				For k = 0 To pcount - 1
					If vertexFloatTransferFlag Then
						fvPtr = At3d_GetFloatXYZ_UV_Array(k, name(0), dataList(index).xyzFloat_uv(k).x, dataList(index).xyzFloat_uv(k).u)
					Else
						fvPtr = At3d_GetXYZ_UV_Array(k, name(0), dataList(index).xyz_uv(k).x, dataList(index).xyz_uv(k).u)
					End If

					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		Dim xyzFlag As Int32 = 1
		If dataList(index).xyz3D Is Nothing And _
		 dataList(index).xyzFloat3D Is Nothing And _
		 dataList(index).xyz_uv Is Nothing And _
		 dataList(index).xyzFloat_uv Is Nothing Then
			xyzFlag = 0
		End If

		Dim tcount As Int32 = At3d_FaceCount(name(0))

		If xyzFlag > 0 And tcount > 0 And errorFlag = 0 Then
			dataList(index).TCount = tcount

			ReDim dataList(index).xyzIndex(tcount)

			Dim conPtr As Int32
			If decisionFlag Then
				If fastFlag Then
					conPtr = At3d_GetAllFaces(name(0), tcount, dataList(index).xyzIndex(0).p0)

					If conPtr = 0 Then
						errorFlag += 1
					End If
				Else
					For k = 0 To tcount - 1
						conPtr = At3d_GetFace(k, name(0), dataList(index).xyzIndex(k).p0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If
			Else
				If fastFlag Then
					conPtr = At3d_GetXYZ_UV_Array_AllFaces(name(0), tcount, dataList(index).xyzIndex(0).p0)

					If conPtr = 0 Then
						errorFlag += 1
					End If
				Else
					For k = 0 To tcount - 1
						conPtr = At3d_GetXYZ_UV_Array_Face(k, name(0), dataList(index).xyzIndex(k).p0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_Face_Verts_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim doFlag As Integer = 1
		Dim errorFlag As Integer = 0
		Dim k As Int32
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		If dataList(index).xyz3D Is Nothing And _
		 dataList(index).xyzFloat3D Is Nothing Then doFlag = 0

		If dataList(index).xyzIndex Is Nothing Then doFlag = 0

		If doFlag > 0 Then
			If At3d_AllocVertexs(name(0), dataList(index).PCount3D) = 0 Then
				errorFlag += 1
			Else
				Dim fvPtr As Int32 = 0

				Dim xyzFloatFlag As Int32 = 0
				If dataList(index).xyz3D Is Nothing Then xyzFloatFlag = 1

				If fastFlag Then
					If xyzFloatFlag Then
						fvPtr = At3d_SetAllFloatVertices(name(0), dataList(index).PCount3D, dataList(index).xyzFloat3D(0).x)
					Else
						fvPtr = At3d_SetAllVertices(name(0), dataList(index).PCount3D, dataList(index).xyz3D(0).x)
					End If

					If fvPtr = 0 Then
						errorFlag += 1
					End If
				Else
					For k = 0 To dataList(index).PCount3D - 1
						If xyzFloatFlag Then
							fvPtr = At3d_SetFloatVertex(k, name(0), dataList(index).xyzFloat3D(k).x)
						Else
							fvPtr = At3d_SetVertex(k, name(0), dataList(index).xyz3D(k).x)
						End If

						If fvPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If

				If errorFlag = 0 Then
					If At3d_AllocFaces(name(0), dataList(index).TCount) = 0 Then
						errorFlag += 1
					Else
						Dim conPtr As Int32
						If fastFlag Then
							conPtr = At3d_SetAllFaces(name(0), dataList(index).TCount, dataList(index).xyzIndex(0).p0)

							If conPtr = 0 Then
								errorFlag += 1
							End If
						Else
							For k = 0 To dataList(index).TCount - 1
								conPtr = At3d_SetFace(k, name(0), dataList(index).xyzIndex(k).p0)

								If conPtr = 0 Then
									errorFlag += 1
									Exit For
								End If
							Next
						End If
					End If
				End If
			End If
		Else
			doFlag = 1
			If dataList(index).xyz_uv Is Nothing And _
			 dataList(index).xyzFloat_uv Is Nothing Then doFlag = 0

			If dataList(index).xyzIndex Is Nothing Then doFlag = 0

			If doFlag Then
				If At3d_AllocVertexs(name(0), dataList(index).xyz_uvCount) = 0 Then
					errorFlag += 1
				Else
					Dim fvPtr As Int32 = 0

					For k = 0 To dataList(index).xyz_uvCount - 1
						If dataList(index).xyz_uv Is Nothing Then
							fvPtr = At3d_SetFloatVertex(k, name(0), dataList(index).xyzFloat_uv(k).x)
						Else
							fvPtr = At3d_SetVertex(k, name(0), dataList(index).xyz_uv(k).x)
						End If

						If fvPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next

					If errorFlag = 0 Then
						If At3d_AllocFaces(name(0), dataList(index).TCount) = 0 Then
							errorFlag += 1
						Else
							Dim conPtr As Int32
							If fastFlag Then
								conPtr = At3d_SetAllFaces(name(0), dataList(index).TCount, dataList(index).xyzIndex(0).p0)

								If conPtr = 0 Then
									errorFlag += 1
								End If
							Else
								For k = 0 To dataList(index).TCount - 1
									conPtr = At3d_SetFace(k, name(0), dataList(index).xyzIndex(k).p0)

									If conPtr = 0 Then
										errorFlag += 1
										Exit For
									End If
								Next
							End If
						End If
					End If
				End If
			End If
		End If

		Return errorFlag

	End Function


	Public Function Transfer_Face_UVs_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim conPtr As Int32
		If At3d_UVPresent(name(0)) Then
			Dim tcount As Int32 = dataList(index).TCount
			Dim doFlag As Int32 = 1
			If dataList(index).xyzIndex Is Nothing Then doFlag = 0
			If doFlag And _
			 transferFromTypeFlag = At3d_TransferFromFlag.TYPE_BASIC Then

				ReDim dataList(index).uv_tri(tcount - 1)

				If fastFlag Then
					conPtr = At3d_GetUV_AllFaces(name(0), tcount, dataList(index).uv_tri(0).u0)

					If conPtr = 0 Then
						errorFlag += 1
					End If
				Else
					Dim k As Int32
					For k = 0 To tcount - 1
						conPtr = At3d_GetUV_Face(k, name(0), dataList(index).uv_tri(k).u0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If
			ElseIf transferFromTypeFlag = At3d_TransferFromFlag.TYPE_ARRAYS Then
				Dim uvcount As Int32 = At3d_UV_Array_Count(name(0))
				If (uvcount) Then

					dataList(index).uvCount = uvcount

					ReDim dataList(index).uv(uvcount - 1)

					ReDim dataList(index).uvIndex(tcount - 1)

					conPtr = At3d_GetUV_Array(name(0), uvcount, dataList(index).uv(0).u)

					If conPtr = 0 Then
						errorFlag += 1
					End If

					If errorFlag = 0 Then
						If fastFlag Then
							conPtr = At3d_GetUV_Array_AllFaces(name(0), tcount, dataList(index).uvIndex(0).p0)

							If conPtr = 0 Then
								errorFlag += 1
							End If
						Else
							Dim k As Int32
							For k = 0 To tcount - 1
								conPtr = At3d_GetUV_Array_Face(k, name(0), dataList(index).uvIndex(k).p0)

								If conPtr = 0 Then
									errorFlag += 1
									Exit For
								End If
							Next
						End If
					End If
				End If
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_Face_UVs_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim doFlag As Integer = 0
		If dataList(index).uv_tri Is Nothing Then
			doFlag = 2
			If dataList(index).uv Is Nothing Then doFlag = 0
			If dataList(index).uvIndex Is Nothing Then doFlag = 0

			If doFlag = 0 And dataList(index).uvPresentFlag Then
				doFlag = 3

				If dataList(index).xyz_uv Is Nothing And _
				 dataList(index).xyzFloat_uv Is Nothing Then doFlag = 0

				If dataList(index).xyzIndex Is Nothing Then doFlag = 0
			End If
		Else
			doFlag = 1
		End If

		Dim conPtr As Int32
		If doFlag = 1 Then
			If fastFlag Then
				conPtr = At3d_SetUV_AllFaces(name(0), dataList(index).TCount, dataList(index).uv_tri(0).u0)

				If conPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To dataList(index).TCount - 1
					conPtr = At3d_SetUV_Face(k, name(0), dataList(index).uv_tri(k).u0)

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		ElseIf doFlag = 2 Then
			Dim i As Int32
			For i = 0 To dataList(index).TCount - 1
				Dim uv(5) As Single
				uv(0) = dataList(index).uv(dataList(index).uvIndex(i).p0).u
				uv(1) = dataList(index).uv(dataList(index).uvIndex(i).p0).v

				uv(2) = dataList(index).uv(dataList(index).uvIndex(i).p1).u
				uv(3) = dataList(index).uv(dataList(index).uvIndex(i).p1).v

				uv(4) = dataList(index).uv(dataList(index).uvIndex(i).p2).u
				uv(5) = dataList(index).uv(dataList(index).uvIndex(i).p2).v

				conPtr = At3d_SetUV_Face(i, name(0), uv(0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		ElseIf doFlag = 3 Then
			Dim i As Int32
			For i = 0 To dataList(index).TCount - 1
				Dim uv(5) As Single

				If dataList(index).xyz_uv Is Nothing Then
					uv(0) = dataList(index).xyzFloat_uv(dataList(index).xyzIndex(i).p0).u
					uv(1) = dataList(index).xyzFloat_uv(dataList(index).xyzIndex(i).p0).v

					uv(2) = dataList(index).xyzFloat_uv(dataList(index).xyzIndex(i).p1).u
					uv(3) = dataList(index).xyzFloat_uv(dataList(index).xyzIndex(i).p1).v

					uv(4) = dataList(index).xyzFloat_uv(dataList(index).xyzIndex(i).p2).u
					uv(5) = dataList(index).xyzFloat_uv(dataList(index).xyzIndex(i).p2).v
				Else
					uv(0) = dataList(index).xyz_uv(dataList(index).xyzIndex(i).p0).u
					uv(1) = dataList(index).xyz_uv(dataList(index).xyzIndex(i).p0).v

					uv(2) = dataList(index).xyz_uv(dataList(index).xyzIndex(i).p1).u
					uv(3) = dataList(index).xyz_uv(dataList(index).xyzIndex(i).p1).v

					uv(4) = dataList(index).xyz_uv(dataList(index).xyzIndex(i).p2).u
					uv(5) = dataList(index).xyz_uv(dataList(index).xyzIndex(i).p2).v
				End If

				conPtr = At3d_SetUV_Face(i, name(0), uv(0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If

		Return errorFlag

	End Function


	Public Function Transfer_Face_VNormals_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim tcount As Int32 = dataList(index).TCount

		' if you check for the presence of vertex normals, you can just read the
		' normals for smooth rendering if they are available
		' otherwise you get normals for flat rendering
		'
		Dim conPtr As Int32
		Dim doFlag As Integer = 1
		If dataList(index).xyzIndex Is Nothing Then doFlag = 0

		If doFlag And _
		 At3d_VertNormPresent(name(0)) > 0 And _
		 transferFromTypeFlag = At3d_TransferFromFlag.TYPE_BASIC Then

			ReDim dataList(index).vnorm_tri(tcount - 1)

			If fastFlag Then
				conPtr = At3d_GetVertNorm_AllFaces(name(0), tcount, dataList(index).vnorm_tri(0).x0, 0)

				If conPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To tcount - 1
					conPtr = At3d_GetVertNorm_Face(k, name(0), dataList(index).vnorm_tri(k).x0, 0)

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		Else
			Dim vnormcount As Int32 = At3d_VertNorm_Array_Count(name(0))

			If vnormcount Then
				dataList(index).vnormCount = vnormcount
				ReDim dataList(index).vnorm(vnormcount - 1)

				ReDim dataList(index).vnormIndex(tcount - 1)

				conPtr = At3d_GetVertNorm_Array(name(0), vnormcount, dataList(index).vnorm(0).x, 0)

				If conPtr = 0 Then
					errorFlag += 1
				End If

				If errorFlag = 0 Then
					If fastFlag Then
						conPtr = At3d_GetVertNorm_Array_AllFaces(name(0), tcount, dataList(index).vnormIndex(0).p0)

						If conPtr = 0 Then
							errorFlag += 1
						End If
					Else
						Dim k As Int32
						For k = 0 To tcount - 1
							conPtr = At3d_GetVertNorm_Array_Face(k, name(0), dataList(index).vnormIndex(k).p0)

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_Face_VNormals_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim conPtr As Int32
		Dim doFlag As Integer = 1
		If dataList(index).vnorm_tri Is Nothing Then
			doFlag = 2
			If dataList(index).vnorm Is Nothing Then doFlag = 0
			If dataList(index).vnormIndex Is Nothing Then doFlag = 0
		End If

		If doFlag = 1 Then
			If fastFlag Then
				conPtr = At3d_SetVertNorm_AllFaces(name(0), dataList(index).TCount, dataList(index).vnorm_tri(0).x0, 0)

				If conPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To dataList(index).TCount - 1
					conPtr = At3d_SetVertNorm_Face(k, name(0), dataList(index).vnorm_tri(k).x0, 0)

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		ElseIf doFlag = 2 Then
			Dim i As Int32
			For i = 0 To dataList(index).TCount - 1
				Dim xyz(8) As Single
				xyz(0) = dataList(index).vnorm(dataList(index).vnormIndex(i).p0).x
				xyz(1) = dataList(index).vnorm(dataList(index).vnormIndex(i).p0).y
				xyz(2) = dataList(index).vnorm(dataList(index).vnormIndex(i).p0).z

				xyz(3) = dataList(index).vnorm(dataList(index).vnormIndex(i).p1).x
				xyz(4) = dataList(index).vnorm(dataList(index).vnormIndex(i).p1).y
				xyz(5) = dataList(index).vnorm(dataList(index).vnormIndex(i).p1).z

				xyz(6) = dataList(index).vnorm(dataList(index).vnormIndex(i).p2).x
				xyz(7) = dataList(index).vnorm(dataList(index).vnormIndex(i).p2).y
				xyz(8) = dataList(index).vnorm(dataList(index).vnormIndex(i).p2).z

				conPtr = At3d_SetVertNorm_Face(i, name(0), xyz(0), 0)

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If

		Return errorFlag

	End Function


	Public Function Transfer_Face_VColors_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim conPtr As Int32
		If At3d_VertColorPresent(name(0)) Then
			Dim tcount As Int32 = dataList(index).TCount
			Dim doFlag As Int32 = 1
			If dataList(index).xyzIndex Is Nothing Then doFlag = 0
			If doFlag And _
			 transferFromTypeFlag = At3d_TransferFromFlag.TYPE_BASIC Then

				ReDim dataList(index).vcolor_tri(tcount - 1)

				If fastFlag Then
					conPtr = At3d_GetVertColor_AllFaces(name(0), tcount, dataList(index).vcolor_tri(0).red0)

					If conPtr = 0 Then
						errorFlag += 1
					End If
				Else
					Dim k As Int32
					For k = 0 To tcount - 1
						conPtr = At3d_GetVertColor_Face(k, name(0), dataList(index).vcolor_tri(k).red0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If
			Else			'If transferFromTypeFlag = At3d_TransferFromFlag.TYPE_ARRAYS Then
				Dim vcolorcount As Int32 = At3d_VertColor_Array_Count(name(0))
				If (vcolorcount) Then

					dataList(index).vcolorCount = vcolorcount

					ReDim dataList(index).vcolor(vcolorcount - 1)

					ReDim dataList(index).vcolorIndex(tcount - 1)

					conPtr = At3d_GetVertColor_Array(name(0), vcolorcount, dataList(index).vcolor(0).red)

					If conPtr = 0 Then
						errorFlag += 1
					End If

					If errorFlag = 0 Then
						If fastFlag Then
							conPtr = At3d_GetVertColor_Array_AllFaces(name(0), tcount, dataList(index).vcolorIndex(0).p0)

							If conPtr = 0 Then
								errorFlag += 1
							End If
						Else
							Dim k As Int32
							For k = 0 To tcount - 1
								conPtr = At3d_GetVertColor_Array_Face(k, name(0), dataList(index).vcolorIndex(k).p0)

								If conPtr = 0 Then
									errorFlag += 1
									Exit For
								End If
							Next
						End If
					End If
				End If
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_Face_VColors_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim doFlag As Integer = 0
		If dataList(index).vcolor_tri Is Nothing Then
			doFlag = 2
			If dataList(index).vcolor Is Nothing Then doFlag = 0
			If dataList(index).vcolorIndex Is Nothing Then doFlag = 0
		Else
			doFlag = 1
		End If

		Dim conPtr As Int32
		If doFlag = 1 Then
			If fastFlag Then
				conPtr = At3d_SetVertColor_AllFaces(name(0), dataList(index).TCount, dataList(index).vcolor_tri(0).red0)

				If conPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To dataList(index).TCount - 1
					conPtr = At3d_SetVertColor_Face(k, name(0), dataList(index).vcolor_tri(k).red0)

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		ElseIf doFlag = 2 Then
			Dim i As Int32
			For i = 0 To dataList(index).TCount - 1
				Dim vcolor(11) As Single
				vcolor(0) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p0).red
				vcolor(1) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p0).green
				vcolor(2) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p0).blue
				vcolor(3) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p0).alpha

				vcolor(4) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p1).red
				vcolor(5) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p1).green
				vcolor(6) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p1).blue
				vcolor(7) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p1).alpha

				vcolor(8) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p2).red
				vcolor(9) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p2).green
				vcolor(10) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p2).blue
				vcolor(11) = dataList(index).vcolor(dataList(index).vcolorIndex(i).p2).alpha

				conPtr = At3d_SetVertColor_Face(i, name(0), vcolor(0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If

		Return errorFlag
	End Function


	Public Function Transfer_Face_Colors_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim tcount As Int32 = dataList(index).TCount
		Dim doFlag As Integer = 1
		If dataList(index).xyzIndex Is Nothing Then doFlag = 0
		If doFlag Then

			ReDim dataList(index).rgb(tcount - 1)

			Dim conPtr As Int32
			If fastFlag Then
				conPtr = At3d_GetAllFaceColors(name(0), tcount, dataList(index).rgb(0).red)

				If conPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To tcount - 1
					conPtr = At3d_GetFaceColor(k, name(0), dataList(index).rgb(k).red)

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_Face_Colors_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim doFlag As Integer = 1
		If dataList(index).rgb Is Nothing Then doFlag = 0

		If doFlag Then
			Dim conPtr As Int32
			If fastFlag Then
				conPtr = At3d_SetAllFaceColors(name(0), dataList(index).TCount, dataList(index).rgb(0).red)

				If conPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To dataList(index).TCount - 1
					conPtr = At3d_SetFaceColor(k, name(0), dataList(index).rgb(k).red)

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		Return errorFlag

	End Function


	Public Function Transfer_2DLines_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim k As Int32
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim pcount As Int32 = At3d_2DVertexCount(name(0))
		If pcount > 0 And errorFlag = 0 Then
			dataList(index).PCount2D = pcount

			' the DLL stores the vertices as double
			' the vertices can be transferred as either
			' double or float between the DLL and the application
			'
			If vertexFloatTransferFlag Then
				ReDim dataList(index).xyzFloat2D(pcount - 1)
			Else
				ReDim dataList(index).xyz2D(pcount - 1)
			End If

			Dim fvPtr As Int32 = 0

			If fastFlag Then
				If vertexFloatTransferFlag Then
					fvPtr = At3d_2DGetAllFloatVertices(name(0), pcount, dataList(index).xyzFloat2D(0).x)
				Else
					fvPtr = At3d_2DGetAllVertices(name(0), pcount, dataList(index).xyz2D(0).x)
				End If

				If fvPtr = 0 Then
					errorFlag += 1
				End If
			Else
				For k = 0 To pcount - 1
					If vertexFloatTransferFlag Then
						fvPtr = At3d_2DGetFloatVertex(k, name(0), dataList(index).xyzFloat2D(k).x)
					Else
						fvPtr = At3d_2DGetVertex(k, name(0), dataList(index).xyz2D(k).x)
					End If

					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If


		Dim ecount As Int32 = At3d_2DEdgeCount(name(0))
		Dim doFlag As Integer = 1

		If dataList(index).xyz2D Is Nothing And _
		 dataList(index).xyzFloat2D Is Nothing Then doFlag = 0

		If doFlag And ecount > 0 And errorFlag = 0 Then
			dataList(index).ECount2D = ecount

			ReDim dataList(index).edge2D(ecount - 1)

			Dim edgePtr As Int32
			If fastFlag Then
				edgePtr = At3d_2DGetAllEdges(name(0), ecount, dataList(index).edge2D(0).p0)

				If edgePtr = 0 Then
					errorFlag += 1
				End If
			Else
				For k = 0 To ecount - 1
					edgePtr = At3d_2DGetEdge(k, name(0), dataList(index).edge2D(k).p0)

					If edgePtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_2DLines_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim k As Int32
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim doFlag As Integer = 1

		If dataList(index).xyz2D Is Nothing And _
		 dataList(index).xyzFloat2D Is Nothing Then doFlag = 0

		If dataList(index).edge2D Is Nothing Then doFlag = 0

		If doFlag Then
			If At3d_2DAllocVertexs(name(0), dataList(index).PCount2D) = 0 Then
				errorFlag += 1
			Else
				Dim fvPtr As Int32 = 0

				If fastFlag Then
					If dataList(index).xyz2D Is Nothing Then
						fvPtr = At3d_2DSetAllFloatVertices(name(0), dataList(index).PCount2D, dataList(index).xyzFloat2D(0).x)
					Else
						fvPtr = At3d_2DSetAllVertices(name(0), dataList(index).PCount2D, dataList(index).xyz2D(0).x)
					End If

					If fvPtr = 0 Then
						errorFlag += 1
					End If
				Else
					For k = 0 To dataList(index).PCount2D - 1
						If dataList(index).xyz2D Is Nothing Then
							fvPtr = At3d_2DSetFloatVertex(k, name(0), dataList(index).xyzFloat2D(k).x)
						Else
							fvPtr = At3d_2DSetVertex(k, name(0), dataList(index).xyz2D(k).x)
						End If

						If fvPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If

				If errorFlag = 0 Then
					If At3d_2DAllocEdges(name(0), dataList(index).ECount2D) = 0 Then
						errorFlag += 1
					Else
						Dim edgePtr As Int32
						If fastFlag Then
							edgePtr = At3d_2DSetAllEdges(name(0), dataList(index).ECount2D, dataList(index).edge2D(0).p0)

							If edgePtr = 0 Then
								errorFlag += 1
							End If
						Else
							For k = 0 To dataList(index).ECount2D - 1
								edgePtr = At3d_2DSetEdge(k, name(0), dataList(index).edge2D(k).p0)

								If edgePtr = 0 Then
									errorFlag += 1
									Exit For
								End If
							Next
						End If
					End If
				End If
			End If
		End If

		Return errorFlag

	End Function


	Public Function Transfer_PointCloud_FromDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim pcount As Int32 = At3d_CloudVertexCount(name(0))
		If pcount > 0 And errorFlag = 0 Then
			dataList(index).PCountCloud = pcount

			If vertexFloatTransferFlag Then
				ReDim dataList(index).xyzFloatCloud(pcount - 1)
			Else
				ReDim dataList(index).xyzCloud(pcount - 1)
			End If

			Dim fvPtr As Int32 = 0

			If fastFlag Then
				If vertexFloatTransferFlag Then
					fvPtr = At3d_CloudGetAllFloatVertices(name(0), pcount, dataList(index).xyzFloatCloud(0).x)
				Else
					fvPtr = At3d_CloudGetAllVertices(name(0), pcount, dataList(index).xyzCloud(0).x)
				End If

				If fvPtr = 0 Then
					errorFlag += 1
				End If
			Else
				Dim k As Int32
				For k = 0 To pcount - 1
					If vertexFloatTransferFlag Then
						fvPtr = At3d_CloudGetFloatVertex(k, name(0), dataList(index).xyzFloatCloud(k).x)
					Else
						fvPtr = At3d_CloudGetVertex(k, name(0), dataList(index).xyzCloud(k).x)
					End If
					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		Return errorFlag
	End Function


	Public Function Transfer_PointCloud_ToDll(ByVal fastFlag As Integer, ByVal index As Integer) As Integer
		Dim errorFlag As Integer = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim doFlag As Integer = 1
		If dataList(index).xyzCloud Is Nothing And _
		 dataList(index).xyzFloatCloud Is Nothing Then doFlag = 0

		If doFlag Then
			If At3d_CloudAllocVertexs(name(0), dataList(index).PCountCloud) = 0 Then
				errorFlag += 1
			Else
				Dim fvPtr As Int32 = 0

				If fastFlag Then
					If dataList(index).xyzCloud Is Nothing Then
						fvPtr = At3d_CloudSetAllFloatVertices(name(0), dataList(index).PCountCloud, dataList(index).xyzFloatCloud(0).x)
					Else
						fvPtr = At3d_CloudSetAllVertices(name(0), dataList(index).PCountCloud, dataList(index).xyzCloud(0).x)
					End If

					If fvPtr = 0 Then
						errorFlag += 1
					End If
				Else
					Dim k As Int32
					For k = 0 To dataList(index).PCountCloud - 1
						If dataList(index).xyzCloud Is Nothing Then
							fvPtr = At3d_CloudSetFloatVertex(k, name(0), dataList(index).xyzFloatCloud(k).x)
						Else
							fvPtr = At3d_CloudSetVertex(k, name(0), dataList(index).xyzCloud(k).x)
						End If

						If fvPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If
			End If
		End If

		Return errorFlag

	End Function


	Public Sub Transfer_Material_FromDll(ByVal index As Integer)
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		At3d_GetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_DXF_COLOR, dataList(index).dxfColor)
		At3d_GetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_DOUBLESIDED, dataList(index).doubleSided)

		At3d_GetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_GEOMETRYSAMPLING, dataList(index).rwxGeometrySampling)
		At3d_GetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_LIGHTSAMPLING, dataList(index).rwxLightSampling)
		At3d_GetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_TEXTUREMODES, dataList(index).rwxTextureModes)
		At3d_GetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_TAG, dataList(index).rwxTag)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_AMBIENT, dataList(index).ambient1)
		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, dataList(index).ambientRGB.red)

		'transfer colorRGB if using ambient1, diffuse1, reflection1 or specular1
		'
		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_COLOR, dataList(index).colorRGB.red)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_DIFFUSE, dataList(index).diffuse1)
		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, dataList(index).diffuseRGB.red)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_REFLECTION, dataList(index).reflection1)
		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_REFLECTION, dataList(index).reflectionRGB.red)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_SPECULAR, dataList(index).specular1)
		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, dataList(index).specularRGB.red)

		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, dataList(index).emissiveRGB.red)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_ROUGHNESS, dataList(index).roughness)
		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_SHININESS, dataList(index).shininess)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_TRANSPARENCY, dataList(index).transparency1)
		At3d_GetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_TRANSPARENCY, dataList(index).transparencyRGB.red)

		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_INDEXREFRACTION, dataList(index).indexRefraction)
		At3d_GetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_CREASEANGLE, dataList(index).creaseAngle)

		Dim texturePathName(MAX_PATH - 1) As Byte
		At3d_GetTextureName(name(0), texturePathName(0))
		If texturePathName(0) <> 0 Then
			dataList(index).texturePathName = AE.GetString(texturePathName)
		End If

		Dim maskPathName(MAX_PATH - 1) As Byte
		At3d_GetMaskName(name(0), maskPathName(0))
		If maskPathName(0) <> 0 Then
			dataList(index).maskPathName = AE.GetString(maskPathName)
		End If
	End Sub


	Public Sub Transfer_Material_ToDll(ByVal index As Integer)
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(dataList(index).name)

		Dim flag As Int32 = 0

		' do this first as ambient1, diffuse1, reflection1 and specular1
		' calculate RGB values based on colorRGB
		'
		If useAmbient1Flag = 1 Then flag = 1
		If useDiffuse1Flag = 1 Then flag = 1
		If useReflection1Flag = 1 Then flag = 1
		If useSpecular1Flag = 1 Then flag = 1
		If flag = 1 Then
			At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_COLOR, dataList(index).colorRGB.red)
		End If

		' do this second
		' diffuse1 and diffuseRGB are linked
		'
		If useDiffuse1Flag = 1 Then
			At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_DIFFUSE, dataList(index).diffuse1)
		Else
			At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, dataList(index).diffuseRGB.red)
		End If

		' ambient1 and ambientRGB are linked
		'
		If useAmbient1Flag = 1 Then
			At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_AMBIENT, dataList(index).ambient1)
		Else
			At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, dataList(index).ambientRGB.red)
		End If

		' reflection1 and reflectionRGB are linked
		'
		If useReflection1Flag = 1 Then
			At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_REFLECTION, dataList(index).reflection1)
		Else
			At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_REFLECTION, dataList(index).reflectionRGB.red)
		End If

		' specular1 and specularRGB are linked
		'
		If useSpecular1Flag = 1 Then
			At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_SPECULAR, dataList(index).specular1)
		Else
			At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, dataList(index).specularRGB.red)
		End If

		At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, dataList(index).emissiveRGB.red)

		At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_ROUGHNESS, dataList(index).roughness)

		At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_SHININESS, dataList(index).shininess)

		' transparency1 and transparencyRGB are linked
		'
		If useTransparency1Flag = 1 Then
			At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_TRANSPARENCY, dataList(index).transparency1)
		Else
			At3d_SetMaterial_F3(name(0), At3d_MatFlag.MATFLAG_F3_TRANSPARENCY, dataList(index).transparencyRGB.red)
		End If

		At3d_SetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_DXF_COLOR, dataList(index).dxfColor)

		At3d_SetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_DOUBLESIDED, dataList(index).doubleSided)

		At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_INDEXREFRACTION, dataList(index).indexRefraction)

		At3d_SetMaterial_F1(name(0), At3d_MatFlag.MATFLAG_F1_CREASEANGLE, dataList(index).creaseAngle)

		At3d_SetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_GEOMETRYSAMPLING, dataList(index).rwxGeometrySampling)
		At3d_SetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_LIGHTSAMPLING, dataList(index).rwxLightSampling)
		At3d_SetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_TEXTUREMODES, dataList(index).rwxTextureModes)
		At3d_SetMaterial_I1(name(0), At3d_MatFlag.MATFLAG_I1_RWX_TAG, dataList(index).rwxTag)

		Dim texturePathName(MAX_PATH - 1) As Byte
		If dataList(index).texturePathName <> Nothing Then
			If dataList(index).texturePathName.Length Then
				Dim name1() As Byte
				name1 = AE.GetBytes(dataList(index).texturePathName)
				At3d_SetTextureName(name(0), name1(0))
			End If
		End If

		Dim maskPathName(MAX_PATH - 1) As Byte
		If dataList(index).maskPathName <> Nothing Then
			If dataList(index).maskPathName.Length Then
				Dim name2() As Byte
				name2 = AE.GetBytes(dataList(index).maskPathName)
				At3d_SetMaskName(name(0), name2(0))
			End If
		End If
	End Sub


	Public Sub TransferFromDll(ByVal fastFlag As Integer)
		' The structures used to hold the data transferred from and to the DLL
		' were designed to show how to use the DLL functions.
		' The structures for your application can be any design that you want
		'
		ClearTransferData()

		dataCount = At3d_LayerCount()
		If dataCount = 0 Then
			Return
		End If

		ReDim dataList(dataCount - 1)

		' if transferFromTypeFlag is TRANSFERFROM_TYPE_ARRAYS or TRANSFERFROM_TYPE_XYZ_UV
		' memory must be allocated and prepared for transfer to take place
		' if flag is TRANSFERFROM_TYPE_BASIC no harm is done by calling function
		'
		' if memory can not be allocated, basic transfer will take place
		'
		Dim oldTransferFromTypeFlag As Int32 = transferFromTypeFlag
		transferFromTypeFlag = At3d_TransferFrom_Start(transferFromTypeFlag)


		Dim layer As Int32 = 0
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim parentName(LEN_LAYER_NAME - 1) As Byte
		Dim errorFlag As Integer = 0

		Dim i As Int32
		For i = 0 To dataCount - 1
			layer = At3d_GetNextLayer(layer, name(0))
			If layer = 0 Then
				Exit For
			End If
			dataList(i).name = AE.GetString(name)

			' only get the name of the parent layer, if it is required
			'
			' a layer hierarchy is required for an avatar
			'
			' if the name of the parent layer is required,
			' it can get be obtained now or
			' after the call to At3d_TransferFrom_Stop()
			'
			At3d_GetLayerParent(name(0), parentName(0))
			dataList(i).parentName = AE.GetString(parentName)


			' only get pivot point for a layer, if it is required
			'
			' a pivot point is required for an avatar
			'
			' if the pivot point for a layer is required,
			' it can get be obtained now or
			' after the call to At3d_TransferFrom_Stop()
			'
			At3d_GetLayerPivotPoint(name(0), dataList(i).pivotPoint.x)


			' transfer 3D faces
			'
			errorFlag = Transfer_Face_Verts_FromDll(fastFlag, i)
			Dim flag As Int32 = 0
			If transferFromTypeFlag = At3d_TransferFromFlag.TYPE_BASIC Then
				flag = 1
			ElseIf transferFromTypeFlag = At3d_TransferFromFlag.TYPE_ARRAYS Then
				flag = 1
			End If
			If errorFlag = 0 And flag = 1 Then
				errorFlag = Transfer_Face_UVs_FromDll(fastFlag, i)
			End If
			If errorFlag = 0 Then
				errorFlag = Transfer_Face_VNormals_FromDll(fastFlag, i)
			End If
			If errorFlag = 0 Then
				errorFlag = Transfer_Face_VColors_FromDll(fastFlag, i)
			End If


			' transfer 2D lines
			'
			If errorFlag = 0 Then
				errorFlag = Transfer_2DLines_FromDll(fastFlag, i)
			End If


			' transfer point cloud (vertices but no edges and faces)
			'
			If errorFlag = 0 Then
				errorFlag = Transfer_PointCloud_FromDll(fastFlag, i)
			End If


			' transfer material properties
			'
			If errorFlag = 0 Then
				Transfer_Material_FromDll(i)
			End If

			If errorFlag Then
				Exit For
			End If
		Next

		If errorFlag Then
			ClearTransferData()
		End If

		' if transferFromTypeFlag is TRANSFERFROM_TYPE_ARRAYS or TRANSFERFROM_TYPE_XYZ_UV
		' memory has to be cleared
		' if flag is TRANSFERFROM_TYPE_BASIC no harm is done by calling function
		'
		At3d_TransferFrom_Stop()
		transferFromTypeFlag = oldTransferFromTypeFlag

	End Sub


	Public Sub TransferToDll(ByVal fastFlag As Integer)
		' The structures used to hold the data transferred from and to the DLL
		' were designed to show how to use the DLL functions.
		' The structures for your application can be any design that you want
		'
		If dataCount = 0 Then
			Return
		End If

		Dim errorFlag As Int32 = 0
		Dim i As Int32
		For i = 0 To dataCount - 1
			'is there a layer name
			'
			Dim doFlag3D As Integer = 1
			Dim doFlag2D As Integer = 1
			Dim doFlagPoints As Integer = 1

			If dataList(i).name Is Nothing Then
				doFlag3D = 0
				doFlag2D = 0
				doFlagPoints = 0
			Else
				'are there 3D faces
				'
				If dataList(i).xyz3D Is Nothing And _
				 dataList(i).xyzFloat3D Is Nothing And _
				 dataList(i).xyz_uv Is Nothing And _
				 dataList(i).xyzFloat_uv Is Nothing Then
					doFlag3D = 0
				End If

				If dataList(i).xyzIndex Is Nothing Then
					doFlag3D = 0
				End If

				'are there 2D lines
				'
				If dataList(i).xyz2D Is Nothing And _
				 dataList(i).xyzFloat2D Is Nothing Then doFlag2D = 0

				If dataList(i).edge2D Is Nothing Then doFlag2D = 0

				'is there a point cloud
				'
				If dataList(i).xyzCloud Is Nothing And _
				 dataList(i).xyzFloatCloud Is Nothing Then doFlagPoints = 0

			End If

			If doFlag3D Or doFlag2D Or doFlagPoints Then
				Dim name() As Byte = AE.GetBytes(dataList(i).name)

				' Create layer
				'
				If At3d_CreateLayer(name(0)) = 0 Then
					Exit For
				End If


				' transfer 3D faces
				'
				If doFlag3D Then
					errorFlag = Transfer_Face_Verts_ToDll(fastFlag, i)
					If errorFlag = 0 Then
						errorFlag = Transfer_Face_UVs_ToDll(fastFlag, i)
					End If
					If errorFlag = 0 Then
						errorFlag = Transfer_Face_VNormals_ToDll(fastFlag, i)
					End If
					If errorFlag = 0 Then
						errorFlag = Transfer_Face_VColors_ToDll(fastFlag, i)
					End If
				End If


				' transfer 2D lines
				'
				If errorFlag = 0 And doFlag2D Then
					errorFlag = Transfer_2DLines_ToDll(fastFlag, i)
				End If


				' transfer point cloud (vertices but no edges or faces
				'
				If errorFlag = 0 And doFlagPoints Then
					errorFlag = Transfer_PointCloud_ToDll(fastFlag, i)
				End If


				' transfer material properties
				'
				If errorFlag = 0 Then
					Transfer_Material_ToDll(i)
				End If

				fileLoaded = 1
			End If

			If errorFlag > 0 Then Exit For
		Next

		At3d_TransferDone()

		If errorFlag = 0 Then
			For i = 0 To dataCount - 1
				If dataList(i).name Is Nothing Then
					' do nothing
				Else
					Dim name() As Byte = AE.GetBytes(dataList(i).name)

					' only set the parent layer, if required
					'
					' a layer hierarchy is required for an avatar
					'
					' all layers must be created before setting the parent layer
					' this can be done before or after calling  At3d_TransferDone()
					'
					If dataList(i).parentName Is Nothing Then
						At3d_SetLayerParent(name(0), 0)
					Else
						Dim parentName() As Byte = AE.GetBytes(dataList(i).parentName)

						At3d_SetLayerParent(name(0), parentName(0))
					End If

					' only set the pivot point for a layer, if required
					'
					' a pivot point for a layer is required for an avatar
					'
					' this can be done before or after calling  At3d_TransferDone()
					'           
					At3d_SetLayerPivotPoint(name(0), dataList(i).pivotPoint.x)

				End If
			Next
		End If

		If errorFlag Then
			Clear_All_Objects()
		End If

	End Sub


	Public Sub ClearTransferData()
		Erase dataList
		dataCount = 0
	End Sub


	Public Sub MergeVertices()
		' for vertices to be duplicates
		' if flag is 0, vertex coordinates must exactly match
		' if flag is 1, vertex coordinates must be <= distance
		'
		Dim distance(2) As Double
		distance(0) = distance(1) = distance(2) = 0.01
		At3d_MergeVertices(0, distance)
	End Sub


	Public Sub DeleteLayer()
		' this test will find and
		' delete the second layer in a linked list
		'
		If At3d_LayerCount() < 2 Then
			Return
		End If

		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32
		layer = At3d_GetNextLayer(0, name(0))

		If layer Then
			layer = At3d_GetNextLayer(layer, name(0))
			If layer Then
				At3d_DeleteLayer(name(0))
			End If
		End If
	End Sub


	Public Sub MakeSmooth1()
		' vertex normals for smooth rendering are calculated for all layers
		' and then the OpenGL view is updated
		'
		At3d_VertNormAllCalculate()
	End Sub


	Public Sub MakeSmooth2()
		' vertex normals for smooth rendering are calculated for each layer
		' and the OpenGL view is updated after the calculations for each layer
		'
		' you select some layers for smooth rendering
		' and other layers for flat rendereing
		'
		' assume the app has not made a list of layer names so just get layer names
		' from DLL and use them
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32
		layer = At3d_GetNextLayer(0, name(0))
		While layer
			At3d_VertNormCalculate(name(0))
			layer = At3d_GetNextLayer(layer, name(0))
		End While
	End Sub


	Public Sub EraseSmooth1()
		' vertex normals for smooth rendering are erased for all layers
		' and then the OpenGL view is updated
		'
		At3d_VertNormAllErase()
	End Sub


	Public Sub EraseSmooth2()
		' vertex normals for smooth rendering are erased for each layer
		' and the OpenGL view is updated after each deletion of normals
		'
		' assume the app has not made a list of layer names so just get layer names
		' from DLL and use them
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32
		layer = At3d_GetNextLayer(0, name(0))
		While layer
			At3d_VertNormErase(name(0))
			layer = At3d_GetNextLayer(layer, name(0))
		End While
	End Sub


	Public Sub SelectFont()
		' do this to prevent a crash
		'
		ResetFPCR()

		Dim dlg As FontDialog = New FontDialog()
		dlg.FontMustExist = True

		Dim style As FontStyle
		If textBoldFlag Then
			If textItalicFlag Then
				style = FontStyle.Bold + FontStyle.Italic
			Else
				style = FontStyle.Bold
			End If
		Else
			If textItalicFlag Then
				style = FontStyle.Italic
			Else
				style = FontStyle.Regular
			End If
		End If

		dlg.Font = New Font(textFaceName, 16.0F, style)

		If dlg.ShowDialog() <> DialogResult.Cancel Then
			If dlg.Font.Bold Then
				textBoldFlag = 1
			Else
				textBoldFlag = 0
			End If

			If dlg.Font.Italic Then
				textItalicFlag = 1
			Else
				textItalicFlag = 0
			End If

			textFaceName = dlg.Font.Name
		End If
	End Sub


	Public Sub GetFontDirectory()
		Dim path1 As String = "c:\"
		If fontPath = Nothing Then
			path1 = "c:\"
		End If

		Dim dlg As New OpenFileDialog()

		dlg.InitialDirectory = path1
		dlg.Filter = "TrueType Font (*.ttf)|*.ttf|All Files (*.*)|*.*"
		dlg.FilterIndex = 1
		dlg.CheckFileExists = True
		dlg.CheckPathExists = True
		dlg.RestoreDirectory = True

		If dlg.ShowDialog() = DialogResult.OK Then
			fontPath = Path.GetDirectoryName(dlg.FileName)
		End If
	End Sub


  Public Sub ConvertText(ByVal unicodeFlag As Int32)
    ' only need to set parameters as they change
    '
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_POINTSPERCURVE, textPoints)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_BOLD, textBoldFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_ITALIC, textItalicFlag)

    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_ON_CURVE, textOnCurveFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_ORIG_VERTS, textOrigVertsFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_ALL_CHARS, textAllCharsFlag)

    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_REDUCE, textReduceFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_JOIN, textJoinFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_FACE, textFaceFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_EXTRUDE, textExtrudeFlag)

    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_LAYERS, textLayersFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_STENCIL, textStencilFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_PLUSCORE, textPlusCoreFlag)
    At3d_WriteFlag(At3d_LibFlag.LIBFLAG_TT_REVERSE_OUTLINES, textReverseOutlinesFlag)

    Dim name1 As Byte()
    If textFaceName <> Nothing Then
      If textFaceName.Length Then
        name1 = AE.GetBytes(textFaceName)
        At3d_TTF_SetFaceName(name1(0))
      End If
    End If

    If fontPath <> Nothing Then
      If fontPath.Length Then
        name1 = AE.GetBytes(fontPath)
        At3d_TTF_SetFontPath(name1(0))
      End If
    End If

    At3d_TTF_SetHeight(textHeight)
    At3d_TTF_SetDepth(textDepth)
    At3d_TTF_SetBorder(textBorder)

    ' convert text - maximum 255 characters
    '
    fileLoaded = 0

    If unicodeFlag Then
      If textUnicodeText <> Nothing Then
        If textUnicodeText.Length Then
          ' convert unicode string to array of characters
          '
          Dim name2 As Char() = textUnicodeText.ToCharArray
          Dim length As Integer = name2.Length

          ' create array to send to DLL and fill with values from character array
          '
          Dim unicodeArray(256) As UInt16
          Dim i As Integer
          For i = 0 To length - 1
            If i < 256 Then
              unicodeArray(i) = AscW(name2(i))
            End If
          Next

          ' add zero value to indicate NULL at the end of the string
          '
          If length < 255 Then
            unicodeArray(length) = 0
          Else
            unicodeArray(255) = 0
          End If

          fileLoaded = At3d_TTF_Unicode_To_3D(unicodeArray(0))
        End If
    End If
    Else
    If textText <> Nothing Then
        If textText.Length Then
          name1 = AE.GetBytes(textText)

          fileLoaded = At3d_TTF_To3D(name1(0))
        End If
    End If
    End If
  End Sub


	Public Sub GetDefaultMaterials()
		At3d_GetDefaultMaterial_I1(At3d_MatFlag.MATFLAG_I1_DXF_COLOR, defaultDxfColor)
		At3d_GetDefaultMaterial_I1(At3d_MatFlag.MATFLAG_I1_DOUBLESIDED, defaultDoubleSided)
		At3d_GetDefaultMaterial_I1(At3d_MatFlag.MATFLAG_I1_RWX_GEOMETRYSAMPLING, defaultRwxGeometrySampling)
		At3d_GetDefaultMaterial_I1(At3d_MatFlag.MATFLAG_I1_RWX_LIGHTSAMPLING, defaultRwxLightSampling)
		At3d_GetDefaultMaterial_I1(At3d_MatFlag.MATFLAG_I1_RWX_TEXTUREMODES, defaultRwxTextureModes)
		At3d_GetDefaultMaterial_I1(At3d_MatFlag.MATFLAG_I1_RWX_TAG, defaultRwxClumpTag)

		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_AMBIENT, defaultAmbient1)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_DIFFUSE, defaultDiffuse1)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_SPECULAR, defaultSpecular1)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_ROUGHNESS, defaultRoughness)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_SHININESS, defaultShininess)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_TRANSPARENCY, defaultTransparency1)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_INDEXREFRACTION, defaultIndexOfRefraction)
		At3d_GetDefaultMaterial_F1(At3d_MatFlag.MATFLAG_F1_CREASEANGLE, defaultCreaseAngle)

		At3d_GetDefaultMaterial_F3(At3d_MatFlag.MATFLAG_F3_AMBIENT, defaultAmbientRGB.red)
		At3d_GetDefaultMaterial_F3(At3d_MatFlag.MATFLAG_F3_COLOR, defaultColorRGB.red)
		At3d_GetDefaultMaterial_F3(At3d_MatFlag.MATFLAG_F3_DIFFUSE, defaultDiffuseRGB.red)
		At3d_GetDefaultMaterial_F3(At3d_MatFlag.MATFLAG_F3_SPECULAR, defaultSpecularRGB.red)
		At3d_GetDefaultMaterial_F3(At3d_MatFlag.MATFLAG_F3_EMISSIVE, defaultEmissiveRGB.red)
		At3d_GetDefaultMaterial_F3(At3d_MatFlag.MATFLAG_F3_TRANSPARENCY, defaultTransparencyRGB.red)
	End Sub


	Public Sub StartStopAlign()
		At3d_AlignActivate()

		' first layer in list is selected first for alignment
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		alignNextLayer = At3d_GetNextLayer(0, name(0))
		alignName = AE.GetString(name)
		At3d_AlignSelectLayer(name(0))
	End Sub


	Public Sub SelectAlignLayer()
		' just select layers in order they are in list
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		alignNextLayer = At3d_GetNextLayer(alignNextLayer, name(0))
		alignName = AE.GetString(name)
		At3d_AlignSelectLayer(name(0))
	End Sub

	Public Sub FlipAlignLayer()
		' use the selected layer
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		name = AE.GetBytes(alignName)
		At3d_AlignDoLayerFlip(name(0))
	End Sub

	Public Sub SpecialTransferFromDll(ByVal fastFlag As Integer)
		' The structures used to hold the data transferred from and to the DLL
		' were designed to show how to use the DLL functions.
		' The structures for your application can be any design that you want
		'
		ClearTransferData()

		dataCount = At3d_LayerCount()
		If dataCount = 0 Then
			Return
		End If


		' The only material property from the layers that is of interest is the
		' color called diffuse
		' For each face on every layer save the diffuse color with the face
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32 = 0
		Dim i As Int32
		If fastFlag Then
			At3d_MarkObjectFaceColor()
		Else
			For i = 0 To dataCount - 1
				layer = At3d_GetNextLayer(layer, name(0))
				If layer Then
					At3d_MarkFaceColor(name(0))
				End If
			Next
		End If


		' Combine all layers into one layer and the DLL will then display
		' the object using only one color
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_MERGE_LAYERS_PROMPT, 0)
		At3d_MergeObjects(1)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_MERGE_LAYERS_PROMPT, 1)

		' Just recheck that there is still an object in the DLL
		' dataCount should equal 1
		'
		dataCount = At3d_LayerCount()
		If dataCount = 0 Then
			Return
		End If

		' allocate storage for the data
		'
		ReDim dataList(dataCount - 1)


		' if transferFromTypeFlag is TRANSFERFROM_TYPE_ARRAYS or TRANSFERFROM_TYPE_XYZ_UV
		' memory must be allocated and prepared for transfer to take place
		' if flag is TRANSFERFROM_TYPE_BASIC no harm is done by calling function
		'
		' if memory can not be allocated, basic transfer will take place
		'
		Dim oldTransferFromTypeFlag As Int32 = transferFromTypeFlag
		transferFromTypeFlag = At3d_TransferFrom_Start(transferFromTypeFlag)


		' get first layer which will be the only layer
		'
		layer = At3d_GetNextLayer(0, name(0))
		If layer Then
			dataList(0).name = AE.GetString(name)

			Dim errorFlag As Integer = 0

			' transfer 3D faces
			'
			errorFlag = Transfer_Face_Verts_FromDll(fastFlag, 0)

			' transfer list of face colors
			'
			If errorFlag = 0 Then
				errorFlag = Transfer_Face_Colors_FromDll(fastFlag, 0)
			End If

			If errorFlag Then
				ClearTransferData()
			End If
		End If

		' if transferFromTypeFlag is TRANSFERFROM_TYPE_ARRAYS or TRANSFERFROM_TYPE_XYZ_UV
		' memory has to be cleared
		' if flag is TRANSFERFROM_TYPE_BASIC no harm is done by calling function
		'
		At3d_TransferFrom_Stop()
		transferFromTypeFlag = oldTransferFromTypeFlag

	End Sub


	Public Sub SpecialTransferToDll(ByVal fastFlag As Integer)
		' The structures used to hold the data transferred from and to the DLL
		' were designed to show how to use the DLL functions.
		' The structures for your application can be any design that you want
		'
		If dataCount = 0 Then
			Return
		End If

		' clear data from DLL
		'
		Clear_All_Objects()

		' there should only be one layer present for the special transfer
		'
		Dim errorFlag As Int32 = 0

		'is there a layer name
		'
		If dataList(0).name Is Nothing Then errorFlag = 1

		'are there 3D faces
		'
		Dim doFlag As Int32 = 1

		If dataList(0).xyz3D Is Nothing And _
		 dataList(0).xyzFloat3D Is Nothing And _
		 dataList(0).xyz_uv Is Nothing And _
		 dataList(0).xyzFloat_uv Is Nothing Then
			doFlag = 0
		End If

		If dataList(0).xyzIndex Is Nothing Then doFlag = 0


		If doFlag Then
			Dim name() As Byte = AE.GetBytes(dataList(0).name)

			' Create layer
			'
			If At3d_CreateLayer(name(0)) = 0 Then
				errorFlag += 1
			End If


			' transfer 3D faces
			'
			If errorFlag = 0 Then
				errorFlag = Transfer_Face_Verts_ToDll(fastFlag, 0)
			End If

			' transfer list of face colors
			'
			If errorFlag = 0 Then
				errorFlag = Transfer_Face_Colors_ToDll(fastFlag, 0)
			End If

			fileLoaded = 1

			At3d_TransferDone()

			If errorFlag Then
				Clear_All_Objects()
			Else
				At3d_DivideFaceColors(name(0))
			End If
		End If

	End Sub


	' a class describing the triangles has indices into the vertex array
	' and the uv coordinates are stored in the struct
	'
	Public Class Triangle1
		Public vertIndex(2) As Int32
		Public uv(2, 1) As Single

		Public Sub New(ByVal p0 As Int32, ByVal p1 As Int32, ByVal p2 As Int32, _
		 ByVal uv0 As Single, ByVal uv1 As Single, ByVal uv2 As Single, _
		 ByVal uv3 As Single, ByVal uv4 As Single, ByVal uv5 As Single)
			Me.vertIndex(0) = p0
			Me.vertIndex(1) = p1
			Me.vertIndex(2) = p2
			Me.uv(0, 0) = uv0
			Me.uv(0, 1) = uv1
			Me.uv(1, 0) = uv2
			Me.uv(1, 1) = uv3
			Me.uv(2, 0) = uv4
			Me.uv(2, 1) = uv5
		End Sub
	End Class

	Public Sub TransferTextureSquareToDll1()
		' a textured square made with two triangles
		'
		'   (-1.0, 0.0,  1.0) 1 ------ 3 (1.0, 0.0,  1.0)
		'                       |\   |
		'                       | \  |
		'                       |  \ |
		'                       |   \|
		'   (-1.0, 0.0, -1.0) 0 ----- 2 (1.0, 0.0, -1.0)
		'
		'  first triangle uses corners: 2, 0, 1
		' second triangle uses corners: 3, 2, 1
		'
		' the vertices are stored as x, y, z
		'
		Dim vertexCount As Int32 = 4
		Dim vertex(,) As Single = New Single(,) { _
		 {-1.0, 0.0, -1.0}, _
		 {-1.0, 0.0, 1.0}, _
		 {1.0, 0.0, -1.0}, _
		 {1.0, 0.0, 1.0} _
		 }

		' a class describing the triangles has indices into the vertex array
		' and the uv coordinates are stored in the struct
		'
		Dim triCount As Int32 = 2

		Dim faces() As Triangle1 = New Triangle1() { _
		 New Triangle1(2, 0, 1, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0), _
		 New Triangle1(3, 2, 1, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0) _
		 }

		' layer name
		' 
		Dim layerName(LEN_LAYER_NAME - 1) As Byte
		layerName = AE.GetBytes("Square")

		' Check layer name and make it legal
		'
		At3d_CheckName(layerName(0))

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0

		' Create layer
		'
		If At3d_CreateLayer(layerName(0)) = 0 Then
			errorFlag += 1
		End If

		' transfer vertices
		'
		Dim i As Int32
		If errorFlag = 0 Then
			If At3d_AllocVertexs(layerName(0), vertexCount) = 0 Then
				errorFlag += 1
			Else
				For i = 0 To vertexCount - 1
					Dim fvPtr As Int32 = 0

					' a float can be transferred as a float or a double
					'
					If vertexFloatTransferFlag Then
						fvPtr = At3d_SetFloatVertex(i, layerName(0), vertex(i, 0))
					Else
						' convert float to double before transfering
						'
						Dim xyz(2) As Double
						xyz(0) = vertex(i, 0)
						xyz(1) = vertex(i, 1)
						xyz(2) = vertex(i, 2)

						fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
					End If

					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If


		' transfer faces
		'
		If errorFlag = 0 Then
			If At3d_AllocFaces(layerName(0), triCount) = 0 Then
				errorFlag += 1
			Else
				' put indices to vertex array into new array
				'
				For i = 0 To triCount - 1
					Dim p(2) As Int32
					p(0) = faces(i).vertIndex(0)
					p(1) = faces(i).vertIndex(1)
					p(2) = faces(i).vertIndex(2)

					Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), p(0))

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		If errorFlag = 0 Then
			For i = 0 To triCount - 1
				Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), faces(i).uv(0, 0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If


		If errorFlag = 0 Then
			' use a texture from the Red Knight
			'
			Dim texturePathName(MAX_PATH - 1) As Byte
			texturePathName = AE.GetBytes("RedHelm.bmp")

			' use defaults created for layer and just transfer texture name
			'
			At3d_SetTextureName(layerName(0), texturePathName(0))
		End If

		If errorFlag > 0 Then
			Clear_All_Objects()
		Else
			At3d_TransferDone()
			fileLoaded = 1

			' need a file name to open FileSaveDialog
			'
			inName = "TextureSquare.cob"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub


	' a class describing the triangles has indices into the vertex and uv arrays
	'
	Public Class Triangle2
		Public vertIndex(2) As Int32
		Public uvIndex(2) As Int32

		Public Sub New(ByVal p0 As Int32, ByVal p1 As Int32, ByVal p2 As Int32, _
		 ByVal uv0 As Int32, ByVal uv1 As Int32, ByVal uv2 As Int32)
			Me.vertIndex(0) = p0
			Me.vertIndex(1) = p1
			Me.vertIndex(2) = p2
			Me.uvIndex(0) = uv0
			Me.uvIndex(1) = uv1
			Me.uvIndex(2) = uv2
		End Sub
	End Class

	Public Sub TransferTextureSquareToDll2()
		' a textured square made with two triangles
		'
		'   (-1.0, 0.0,  1.0) 1 ------ 3 (1.0, 0.0,  1.0)
		'                       |\   |
		'                       | \  |
		'                       |  \ |
		'                       |   \|
		'   (-1.0, 0.0, -1.0) 0 ----- 2 (1.0, 0.0, -1.0)
		'
		'  first triangle uses corners: 2, 0, 1
		' second triangle uses corners: 3, 2, 1
		'
		' the vertices are stored as x, y, z
		'
		Dim vertexCount As Int32 = 4
		Dim vertex(,) As Single = New Single(,) { _
		 {-1.0, 0.0, -1.0}, _
		 {-1.0, 0.0, 1.0}, _
		 {1.0, 0.0, -1.0}, _
		 {1.0, 0.0, 1.0} _
		 }

		' the texture coordinates are stored as u, v
		'
		Dim uv(,) As Single = New Single(,) { _
		 {0.0, 0.0}, _
		 {2.0, 0.0}, _
		 {2.0, 2.0}, _
		 {0.0, 2.0} _
		 }

		' a class describing the triangles has indices into the vertex and uv arrays
		'
		Dim triCount As Int32 = 2

		Dim faces() As Triangle2 = New Triangle2() { _
		 New Triangle2(2, 0, 1, 1, 0, 3), _
		 New Triangle2(3, 2, 1, 2, 1, 3) _
		 }

		' layer name
		' 
		Dim layerName(LEN_LAYER_NAME - 1) As Byte
		layerName = AE.GetBytes("Square")

		' Check layer name and make it legal
		'
		At3d_CheckName(layerName(0))

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0

		' Create layer
		'
		If At3d_CreateLayer(layerName(0)) = 0 Then
			errorFlag += 1
		End If

		' transfer vertices
		'
		Dim i As Int32
		If errorFlag = 0 Then
			If At3d_AllocVertexs(layerName(0), vertexCount) = 0 Then
				errorFlag += 1
			Else
				For i = 0 To vertexCount - 1
					Dim fvPtr As Int32 = 0

					If vertexFloatTransferFlag Then
						fvPtr = At3d_SetFloatVertex(i, layerName(0), vertex(i, 0))
					Else
						' convert float to double before transfering
						'
						Dim xyz(2) As Double
						xyz(0) = vertex(i, 0)
						xyz(1) = vertex(i, 1)
						xyz(2) = vertex(i, 2)

						fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
					End If

					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		' transfer faces
		'
		If errorFlag = 0 Then
			If At3d_AllocFaces(layerName(0), triCount) = 0 Then
				errorFlag += 1
			Else
				' put indices to vertex array into new array
				'
				For i = 0 To triCount - 1
					Dim p(2) As Int32
					p(0) = faces(i).vertIndex(0)
					p(1) = faces(i).vertIndex(1)
					p(2) = faces(i).vertIndex(2)

					Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), p(0))

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		If errorFlag = 0 Then
			For i = 0 To triCount - 1
				' get indices into the uv list
				'
				Dim p0 As Int32 = faces(i).uvIndex(0)
				Dim p1 As Int32 = faces(i).uvIndex(1)
				Dim p2 As Int32 = faces(i).uvIndex(2)

				' set the UV list for this triangle
				'
				Dim uvTemp(5) As Single
				uvTemp(0) = uv(p0, 0)
				uvTemp(1) = uv(p0, 1)

				uvTemp(2) = uv(p1, 0)
				uvTemp(3) = uv(p1, 1)

				uvTemp(4) = uv(p2, 0)
				uvTemp(5) = uv(p2, 1)

				Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uvTemp(0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If


		If errorFlag = 0 Then
			' use a texture from the Green Knight
			'
			Dim texturePathName(MAX_PATH - 1) As Byte
			texturePathName = AE.GetBytes("GreenHelm.bmp")

			' use defaults created for layer and just transfer texture name
			'
			At3d_SetTextureName(layerName(0), texturePathName(0))
		End If

		If errorFlag > 0 Then
			Clear_All_Objects()
		Else
			At3d_TransferDone()
			fileLoaded = 1

			' need a file name to open FileSaveDialog
			'
			inName = "TextureSquare.cob"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub


	' a class describing the triangles has indices into the vertex and uv arrays
	'
	Public Class Triangle3
		Public vertIndex(2) As Int32

		Public Sub New(ByVal p0 As Int32, ByVal p1 As Int32, ByVal p2 As Int32)
			Me.vertIndex(0) = p0
			Me.vertIndex(1) = p1
			Me.vertIndex(2) = p2
		End Sub
	End Class

	Public Sub TransferTextureSquareToDll3()
		' a textured square made with two triangles
		'
		'   (-1.0, 0.0,  1.0) 1 ------ 3 (1.0, 0.0,  1.0)
		'                       |\   |
		'                       | \  |
		'                       |  \ |
		'                       |   \|
		'   (-1.0, 0.0, -1.0) 0 ----- 2 (1.0, 0.0, -1.0)
		'
		'  first triangle uses corners: 2, 0, 1
		' second triangle uses corners: 3, 2, 1
		'
		' the vertex and texture coordinates are stored together
		' as x, y, z, u, v
		'
		Dim vertexUVCount As Int32 = 6
		Dim vertex_uv(,) As Single = New Single(,) { _
		 {1.0, 0.0, -1.0, 3.0, 0.0}, _
		 {-1.0, 0.0, -1.0, 0.0, 0.0}, _
		 {-1.0, 0.0, 1.0, 0.0, 3.0}, _
		 {1.0, 0.0, 1.0, 3.0, 3.0}, _
		 {1.0, 0.0, -1.0, 3.0, 0.0}, _
		 {-1.0, 0.0, 1.0, 0.0, 3.0} _
		 }

		' order of vertices in the two triangles is the same as the vertex_uv list
		'
		Dim triCount As Int32 = 2

		Dim faces() As Triangle3 = New Triangle3() { _
		 New Triangle3(0, 1, 2), _
		 New Triangle3(3, 4, 5) _
		 }

		' layer name
		' 
		Dim layerName(LEN_LAYER_NAME - 1) As Byte
		layerName = AE.GetBytes("Square")

		' Check layer name and make it legal
		'
		At3d_CheckName(layerName(0))

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0

		' Create layer
		'
		If At3d_CreateLayer(layerName(0)) = 0 Then
			errorFlag += 1
		End If

		' transfer vertices
		'
		Dim i As Int32
		If errorFlag = 0 Then
			If At3d_AllocVertexs(layerName(0), vertexUVCount) = 0 Then
				errorFlag += 1
			Else
				For i = 0 To vertexUVCount - 1
					Dim fvPtr As Int32 = 0

					If vertexFloatTransferFlag Then
						fvPtr = At3d_SetFloatVertex(i, layerName(0), vertex_uv(i, 0))
					Else
						' convert float to double before transfering
						'
						Dim xyz(2) As Double
						xyz(0) = vertex_uv(i, 0)
						xyz(1) = vertex_uv(i, 1)
						xyz(2) = vertex_uv(i, 2)

						fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
					End If

					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If


		' transfer faces
		'
		If errorFlag = 0 Then
			If At3d_AllocFaces(layerName(0), triCount) = 0 Then
				errorFlag += 1
			Else
				For i = 0 To triCount - 1
					Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), faces(i).vertIndex(0))

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If


		If errorFlag = 0 Then
			For i = 0 To triCount - 1
				' get indices into the vertex_uv list
				'
				Dim p0 As Int32 = faces(i).vertIndex(0)
				Dim p1 As Int32 = faces(i).vertIndex(1)
				Dim p2 As Int32 = faces(i).vertIndex(2)

				' set the UV list for this triangle
				'
				Dim uv(5) As Single
				uv(0) = vertex_uv(p0, 3)
				uv(1) = vertex_uv(p0, 4)

				uv(2) = vertex_uv(p1, 3)
				uv(3) = vertex_uv(p1, 4)

				uv(4) = vertex_uv(p2, 3)
				uv(5) = vertex_uv(p2, 4)

				Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uv(0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If


		If errorFlag = 0 Then
			' use a texture from the Blue Knight
			'
			Dim texturePathName(MAX_PATH - 1) As Byte
			texturePathName = AE.GetBytes("BlueHelm.bmp")

			' use defaults created for layer and just transfer texture name
			'
			At3d_SetTextureName(layerName(0), texturePathName(0))
		End If

		If errorFlag > 0 Then
			Clear_All_Objects()
		Else
			At3d_TransferDone()
			fileLoaded = 1

			' need a file name to open FileSaveDialog
			'
			inName = "TextureSquare.cob"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub


	Public Sub TransferRedKnightToDll()
		redKnight = New CRedKnight()

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0
		Dim k As Int32
		For k = 0 To redKnight.layerCount - 1
			Dim dataPtr As CRedKnight.TEST_3D_DATA1 = redKnight.data1(k)

			Dim doFlag As Int32 = 1
			If dataPtr.name Is Nothing Then doFlag = 0
			If dataPtr.xyz Is Nothing Then doFlag = 0
			If dataPtr.triangle Is Nothing Then doFlag = 0

			If doFlag > 0 Then

				Dim layerName(LEN_LAYER_NAME - 1) As Byte
				layerName = AE.GetBytes(dataPtr.name)

				' Check layer name
				'
				At3d_CheckName(layerName(0))

				' Create layer
				'
				If At3d_CreateLayer(layerName(0)) = 0 Then
					errorFlag += 1
				End If

				' transfer vertices
				'
				Dim i As Int32
				If errorFlag = 0 Then
					If At3d_AllocVertexs(layerName(0), dataPtr.xyzCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.xyzCount - 1
							Dim fvPtr As Int32 = 0

							' a float can be transferred as a float or a double
							'
							If vertexFloatTransferFlag Then
								fvPtr = At3d_SetFloatVertex(i, layerName(0), dataPtr.xyz(i).x)
							Else
								' convert float to double before transfering
								'
								Dim xyz(2) As Double
								xyz(0) = dataPtr.xyz(i).x
								xyz(1) = dataPtr.xyz(i).y
								xyz(2) = dataPtr.xyz(i).z

								fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
							End If

							If fvPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If

				' transfer faces
				'
				If errorFlag = 0 Then
					If At3d_AllocFaces(layerName(0), dataPtr.triangleCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.triangleCount - 1
							Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), dataPtr.triangle(i).xyzIndex(0))

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If

				If errorFlag = 0 And dataPtr.uvFlag > 0 Then
					For i = 0 To dataPtr.triangleCount - 1
						Dim uv(5) As Single
						uv(0) = dataPtr.triangle(i).uv(0).u
						uv(1) = dataPtr.triangle(i).uv(0).v

						uv(2) = dataPtr.triangle(i).uv(1).u
						uv(3) = dataPtr.triangle(i).uv(1).v

						uv(4) = dataPtr.triangle(i).uv(2).u
						uv(5) = dataPtr.triangle(i).uv(2).v

						Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uv(0))

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If

				If errorFlag = 0 And dataPtr.normalFlag > 0 Then
					For i = 0 To dataPtr.triangleCount - 1
						Dim normal(8) As Single
						normal(0) = dataPtr.triangle(i).normal(0).x
						normal(1) = dataPtr.triangle(i).normal(0).y
						normal(2) = dataPtr.triangle(i).normal(0).z

						normal(3) = dataPtr.triangle(i).normal(1).x
						normal(4) = dataPtr.triangle(i).normal(1).y
						normal(5) = dataPtr.triangle(i).normal(1).z

						normal(6) = dataPtr.triangle(i).normal(2).x
						normal(7) = dataPtr.triangle(i).normal(2).y
						normal(8) = dataPtr.triangle(i).normal(2).z

						Dim conPtr As Int32 = At3d_SetVertNorm_Face(i, layerName(0), normal(0), 0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If

				If errorFlag = 0 Then
					At3d_SetMaterial_I1(layerName(0), At3d_MatFlag.MATFLAG_I1_DXF_COLOR, dataPtr.dxfColor)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, dataPtr.ambientRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, dataPtr.diffuseRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, dataPtr.specularRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, dataPtr.emissiveRGB.red)

					If dataPtr.texturePathName <> Nothing Then
						Dim texturePathName(MAX_PATH - 1) As Byte
						texturePathName = AE.GetBytes(dataPtr.texturePathName)

						At3d_SetTextureName(layerName(0), texturePathName(0))
					End If
				End If

				If errorFlag = 0 Then fileLoaded = 1
			End If

			If errorFlag > 0 Then
				Clear_All_Objects()
				Exit For

			End If
		Next

		If errorFlag = 0 Then
			At3d_TransferDone()

			' need a file name to open FileSaveDialog
			'
			inName = "RedKnight.lwo"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub


	Public Sub TransferGreenKnightToDll()
		greenKnight = New CGreenKnight()

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0
		Dim k As Int32
		For k = 0 To greenKnight.layerCount - 1
			Dim dataPtr As CGreenKnight.TEST_3D_DATA2 = greenKnight.data2(k)

			Dim doFlag As Int32 = 1
			If dataPtr.name Is Nothing Then doFlag = 0
			If dataPtr.xyz Is Nothing Then doFlag = 0
			If dataPtr.triangle Is Nothing Then doFlag = 0

			If doFlag > 0 Then

				Dim layerName(LEN_LAYER_NAME - 1) As Byte
				layerName = AE.GetBytes(dataPtr.name)

				' Check layer name
				'
				At3d_CheckName(layerName(0))

				' Create layer
				'
				If At3d_CreateLayer(layerName(0)) = 0 Then
					errorFlag += 1
				End If

				' transfer vertices
				'
				Dim i As Int32
				If errorFlag = 0 Then
					If At3d_AllocVertexs(layerName(0), dataPtr.xyzCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.xyzCount - 1
							Dim fvPtr As Int32 = 0

							' a float can be transferred as a double or a float
							'
							If vertexFloatTransferFlag Then
								fvPtr = At3d_SetFloatVertex(i, layerName(0), dataPtr.xyz(i).x)
							Else
								' convert float to double before transfering
								'
								Dim xyz(2) As Double
								xyz(0) = dataPtr.xyz(i).x
								xyz(1) = dataPtr.xyz(i).y
								xyz(2) = dataPtr.xyz(i).z

								fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
							End If

							If fvPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If

					' transfer faces
					'
					If errorFlag = 0 Then
						If At3d_AllocFaces(layerName(0), dataPtr.triangleCount) = 0 Then
							errorFlag += 1
						Else
							For i = 0 To dataPtr.triangleCount - 1
								Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), dataPtr.triangle(i).xyzIndex(0))

								If conPtr = 0 Then
									errorFlag += 1
									Exit For
								End If
							Next
						End If
					End If

					doFlag = 1
					If dataPtr.uv Is Nothing Then doFlag = 0
					If errorFlag = 0 And doFlag Then
						For i = 0 To dataPtr.triangleCount - 1
							Dim uv(5) As Single
							uv(0) = dataPtr.uv(dataPtr.triangle(i).uvIndex(0)).u
							uv(1) = dataPtr.uv(dataPtr.triangle(i).uvIndex(0)).v

							uv(2) = dataPtr.uv(dataPtr.triangle(i).uvIndex(1)).u
							uv(3) = dataPtr.uv(dataPtr.triangle(i).uvIndex(1)).v

							uv(4) = dataPtr.uv(dataPtr.triangle(i).uvIndex(2)).u
							uv(5) = dataPtr.uv(dataPtr.triangle(i).uvIndex(2)).v

							Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uv(0))

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If

					doFlag = 1
					If dataPtr.normal Is Nothing Then doFlag = 0
					If errorFlag = 0 And doFlag Then
						For i = 0 To dataPtr.triangleCount - 1
							Dim normal(8) As Single
							normal(0) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).x
							normal(1) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).y
							normal(2) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).z

							normal(3) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).x
							normal(4) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).y
							normal(5) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).z

							normal(6) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).x
							normal(7) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).y
							normal(8) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).z

							Dim conPtr As Int32 = At3d_SetVertNorm_Face(i, layerName(0), normal(0), 0)

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If


					If errorFlag = 0 Then
						At3d_SetMaterial_I1(layerName(0), At3d_MatFlag.MATFLAG_I1_DXF_COLOR, dataPtr.dxfColor)

						At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, dataPtr.ambientRGB.red)

						At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, dataPtr.diffuseRGB.red)

						At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, dataPtr.specularRGB.red)

						At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, dataPtr.emissiveRGB.red)

						If dataPtr.texturePathName <> Nothing Then
							Dim texturePathName(MAX_PATH - 1) As Byte
							texturePathName = AE.GetBytes(dataPtr.texturePathName)

							At3d_SetTextureName(layerName(0), texturePathName(0))
						End If
					End If

					If errorFlag = 0 Then fileLoaded = 1
				End If

				If errorFlag > 0 Then
					Clear_All_Objects()
					Exit For
				End If
			End If
		Next

		If errorFlag = 0 Then
			At3d_TransferDone()

			' need a file name to open FileSaveDialog
			'
			inName = "GreenKnight.lwo"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub


	Public Sub TransferBlueKnightToDll()
		blueKnight = New CBlueKnight()

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0
		Dim k As Int32
		For k = 0 To blueKnight.layerCount - 1
			Dim dataPtr As CBlueKnight.TEST_3D_DATA3 = blueKnight.data3(k)

			Dim doFlag As Int32 = 1
			If dataPtr.name Is Nothing Then doFlag = 0
			If dataPtr.xyz_uv Is Nothing Then doFlag = 0
			If dataPtr.triangle Is Nothing Then doFlag = 0

			If doFlag Then
				Dim layerName(LEN_LAYER_NAME - 1) As Byte
				layerName = AE.GetBytes(dataPtr.name)

				' Check layer name
				'
				At3d_CheckName(layerName(0))

				' Create layer
				'
				If At3d_CreateLayer(layerName(0)) = 0 Then
					errorFlag += 1
				End If

				' transfer vertices
				'
				Dim i As Int32
				If errorFlag = 0 Then
					If At3d_AllocVertexs(layerName(0), dataPtr.xyz_uvCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.xyz_uvCount - 1
							Dim fvPtr As Int32 = 0

							' a float can be transferred as a double or a float
							'
							If vertexFloatTransferFlag Then
								fvPtr = At3d_SetFloatVertex(i, layerName(0), dataPtr.xyz_uv(i).x)
							Else
								' convert float to double before transfering
								'
								Dim xyz(2) As Double
								xyz(0) = dataPtr.xyz_uv(i).x
								xyz(1) = dataPtr.xyz_uv(i).y
								xyz(2) = dataPtr.xyz_uv(i).z

								fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
							End If

							If fvPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If

				' transfer faces
				'
				If errorFlag = 0 Then
					If At3d_AllocFaces(layerName(0), dataPtr.triangleCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.triangleCount - 1
							Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), dataPtr.triangle(i).xyz_uvIndex(0))

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If

				doFlag = 1
				If dataPtr.xyz_uv Is Nothing Then doFlag = 0
				If errorFlag = 0 And doFlag And dataPtr.uvFlag Then
					For i = 0 To dataPtr.triangleCount - 1
						Dim uv(5) As Single
						uv(0) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(0)).u
						uv(1) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(0)).v

						uv(2) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(1)).u
						uv(3) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(1)).v

						uv(4) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(2)).u
						uv(5) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(2)).v

						Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uv(0))

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If

				doFlag = 1
				If dataPtr.normal Is Nothing Then doFlag = 0
				If errorFlag = 0 And doFlag > 0 Then
					For i = 0 To dataPtr.triangleCount - 1
						Dim normal(8) As Single
						normal(0) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).x
						normal(1) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).y
						normal(2) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).z

						normal(3) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).x
						normal(4) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).y
						normal(5) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).z

						normal(6) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).x
						normal(7) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).y
						normal(8) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).z

						Dim conPtr As Int32 = At3d_SetVertNorm_Face(i, layerName(0), normal(0), 0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If


				If errorFlag = 0 Then
					At3d_SetMaterial_I1(layerName(0), At3d_MatFlag.MATFLAG_I1_DXF_COLOR, dataPtr.dxfColor)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, dataPtr.ambientRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, dataPtr.diffuseRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, dataPtr.specularRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, dataPtr.emissiveRGB.red)

					If dataPtr.texturePathName <> Nothing Then
						Dim texturePathName(MAX_PATH - 1) As Byte
						texturePathName = AE.GetBytes(dataPtr.texturePathName)

						At3d_SetTextureName(layerName(0), texturePathName(0))
					End If
				End If

				If errorFlag = 0 Then fileLoaded = 1
			End If

			If errorFlag > 0 Then
				Clear_All_Objects()
				Exit For
			End If
		Next

		If errorFlag = 0 Then
			At3d_TransferDone()

			' need a file name to open FileSaveDialog
			'
			inName = "BlueKnight.lwo"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub

	Public Sub TransferGreenMonkToDLL()
		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		greenMonk = New CGreenMonk()

		Dim doFlag As Int32 = 1

		' GreenMonk is one 3D object with multiple materials assigned to the triangles
		'
		' Create one layer for each material
		' store the pointer to the layer that is created
		' copy the material data to the layer
		'
		If greenMonk.xyz Is Nothing Then doFlag = 0
		If greenMonk.triangle4 Is Nothing Then doFlag = 0
		If doFlag = 0 Then Return

		Dim layerName(LEN_LAYER_NAME - 1) As Byte
		Dim errorFlag As Int32 = 0
		Dim k As Int32
		For k = 0 To greenMonk.materialCount - 1
			If greenMonk.dataMaterial(k).name Is Nothing Then doFlag = 0

			If doFlag = 0 Then
				errorFlag += 1
				Exit For
			End If

			layerName = AE.GetBytes(greenMonk.dataMaterial(k).name)

			' Check layer name
			'
			At3d_CheckName(layerName(0))

			' Create layer
			'
			Dim layerPtr As Int32
			layerPtr = At3d_CreateLayer(layerName(0))
			If layerPtr = 0 Then
				errorFlag += 1
				Exit For
			Else
				' save pointer to the layer
				'
				greenMonk.dataMaterial(k).layerPtr = layerPtr

				' material properties can be set before or after
				' dividing the object into multiple objects
				'
				At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, greenMonk.dataMaterial(k).ambientRGB.red)

				At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, greenMonk.dataMaterial(k).diffuseRGB.red)

				At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, greenMonk.dataMaterial(k).specularRGB.red)

				At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, greenMonk.dataMaterial(k).emissiveRGB.red)

				If greenMonk.dataMaterial(k).texturePathName <> Nothing Then
					Dim texturePathName(MAX_PATH - 1) As Byte
					texturePathName = AE.GetBytes(greenMonk.dataMaterial(k).texturePathName)

					At3d_SetTextureName(layerName(0), texturePathName(0))
				End If
			End If
		Next

		' pick any layer
		'
		Dim materialIndex As Int32 = 2
		layerName = AE.GetBytes(greenMonk.dataMaterial(materialIndex).name)

		' transfer vertices
		'
		Dim i As Int32
		If errorFlag = 0 Then
			If At3d_AllocVertexs(layerName(0), greenMonk.xyzCount) = 0 Then
				errorFlag += 1
			Else
				For i = 0 To greenMonk.xyzCount - 1
					Dim fvPtr As Int32 = 0

					' a float can be transferred as a double or a float
					'
					If vertexFloatTransferFlag Then
						fvPtr = At3d_SetFloatVertex(i, layerName(0), greenMonk.xyz(i).x)
					Else
						' convert float to double before transfering
						'
						Dim xyz(2) As Double
						xyz(0) = greenMonk.xyz(i).x
						xyz(1) = greenMonk.xyz(i).y
						xyz(2) = greenMonk.xyz(i).z

						fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
					End If

					If fvPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		' transfer faces
		'
		If errorFlag = 0 Then
			If At3d_AllocFaces(layerName(0), greenMonk.triangleCount) = 0 Then
				errorFlag += 1
			Else
				For i = 0 To greenMonk.triangleCount - 1
					Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), greenMonk.triangle4(i).xyzIndex(0))

					If conPtr = 0 Then
						errorFlag += 1
						Exit For
					End If
				Next
			End If
		End If

		' transfer UV coordinates
		'
		doFlag = 1
		If greenMonk.uv Is Nothing Then doFlag = 0
		If errorFlag = 0 And doFlag Then
			For i = 0 To greenMonk.triangleCount - 1
				Dim uv(5) As Single
				uv(0) = greenMonk.uv(greenMonk.triangle4(i).uvIndex(0)).u
				uv(1) = greenMonk.uv(greenMonk.triangle4(i).uvIndex(0)).v

				uv(2) = greenMonk.uv(greenMonk.triangle4(i).uvIndex(1)).u
				uv(3) = greenMonk.uv(greenMonk.triangle4(i).uvIndex(1)).v

				uv(4) = greenMonk.uv(greenMonk.triangle4(i).uvIndex(2)).u
				uv(5) = greenMonk.uv(greenMonk.triangle4(i).uvIndex(2)).v

				Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uv(0))

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If

		' transfer normals
		'
		doFlag = 1
		If greenMonk.normal Is Nothing Then doFlag = 0
		If errorFlag = 0 And doFlag > 0 Then
			For i = 0 To greenMonk.triangleCount - 1
				Dim normal(8) As Single
				normal(0) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(0)).x
				normal(1) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(0)).y
				normal(2) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(0)).z

				normal(3) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(1)).x
				normal(4) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(1)).y
				normal(5) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(1)).z

				normal(6) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(2)).x
				normal(7) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(2)).y
				normal(8) = greenMonk.normal(greenMonk.triangle4(i).normalIndex(2)).z

				Dim conPtr As Int32 = At3d_SetVertNorm_Face(i, layerName(0), normal(0), 0)

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If

		' transfer layer pointers
		'
		If errorFlag = 0 Then
			For i = 0 To greenMonk.triangleCount - 1
				Dim conPtr As Int32 = At3d_SetFaceLayerPointer(i, layerName(0), greenMonk.dataMaterial(greenMonk.triangle4(i).materialIndex).layerPtr)

				If conPtr = 0 Then
					errorFlag += 1
					Exit For
				End If
			Next
		End If

		If errorFlag = 0 Then fileLoaded = 1

		If errorFlag > 0 Then
			Clear_All_Objects()
		End If

		If errorFlag = 0 Then
			At3d_TransferDone()

			At3d_DivideFaceLayerPointers(layerName(0))

			' when UV coordinates are transferred all layers
			' are marked as containing textures even if they do not
			' clear UV coordinates from layers that are not textured
			'
			doFlag = 1
			If greenMonk.uv Is Nothing Then doFlag = 0
			If doFlag Then

				For i = 0 To greenMonk.materialCount - 1
					If greenMonk.dataMaterial(i).texturePathName = Nothing Then
						layerName = AE.GetBytes(greenMonk.dataMaterial(i).name)
						At3d_Remove_UV_Coordinates(layerName(0))
					End If
				Next
			End If

			' need a file name to open FileSaveDialog
			'
			inName = "GreenMonk.lwo"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub

	Public Sub TransferBlueMonkToDLL()
		' this test works the same as TransferBlueKnightToDll()
		' except for one change
		'
		blueMonk = New CBlueMonk()

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		Dim errorFlag As Int32 = 0
		Dim k As Int32
		For k = 0 To blueMonk.layerCount - 1
			Dim dataPtr As CBlueMonk.TEST_3D_DATA4 = blueMonk.data4(k)

			Dim doFlag As Int32 = 1
			If dataPtr.name Is Nothing Then doFlag = 0
			If dataPtr.xyz_uv Is Nothing Then doFlag = 0
			If dataPtr.triangle Is Nothing Then doFlag = 0

			If doFlag Then
				Dim layerName(LEN_LAYER_NAME - 1) As Byte
				layerName = AE.GetBytes(dataPtr.name)

				' Check layer name
				'
				At3d_CheckName(layerName(0))

				' Create layer
				'
				If At3d_CreateLayer(layerName(0)) = 0 Then
					errorFlag += 1
				End If

				' this test works the same as TransferBlueKnightToDll()
				' except for one change:
				' the vertices are all defined in a local coordinate system
				' a transformation matrix has to be set in the DLL
				' to convert the vertices from a local to the world coordinate system
				'
				doFlag = 1
				If dataPtr.matrix Is Nothing Then doFlag = 0
				If errorFlag = 0 And doFlag Then
					If At3d_SetLayerTransform(layerName(0), dataPtr.matrix(0)) = 0 Then
						errorFlag += 1
					End If
				End If

				' transfer vertices
				'
				Dim i As Int32
				If errorFlag = 0 Then
					If At3d_AllocVertexs(layerName(0), dataPtr.xyz_uvCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.xyz_uvCount - 1
							Dim fvPtr As Int32 = 0

							' a float can be transferred as a double or a float
							'
							If vertexFloatTransferFlag Then
								fvPtr = At3d_SetFloatVertex(i, layerName(0), dataPtr.xyz_uv(i).x)
							Else
								' convert float to double before transfering
								'
								Dim xyz(2) As Double
								xyz(0) = dataPtr.xyz_uv(i).x
								xyz(1) = dataPtr.xyz_uv(i).y
								xyz(2) = dataPtr.xyz_uv(i).z

								fvPtr = At3d_SetVertex(i, layerName(0), xyz(0))
							End If

							If fvPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If

				' transfer faces
				'
				If errorFlag = 0 Then
					If At3d_AllocFaces(layerName(0), dataPtr.triangleCount) = 0 Then
						errorFlag += 1
					Else
						For i = 0 To dataPtr.triangleCount - 1
							Dim conPtr As Int32 = At3d_SetFace(i, layerName(0), dataPtr.triangle(i).xyz_uvIndex(0))

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						Next
					End If
				End If

				doFlag = 1
				If dataPtr.xyz_uv Is Nothing Then doFlag = 0
				If errorFlag = 0 And doFlag And dataPtr.uvFlag Then
					For i = 0 To dataPtr.triangleCount - 1
						Dim uv(5) As Single
						uv(0) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(0)).u
						uv(1) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(0)).v

						uv(2) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(1)).u
						uv(3) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(1)).v

						uv(4) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(2)).u
						uv(5) = dataPtr.xyz_uv(dataPtr.triangle(i).xyz_uvIndex(2)).v

						Dim conPtr As Int32 = At3d_SetUV_Face(i, layerName(0), uv(0))

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If

				doFlag = 1
				If dataPtr.normal Is Nothing Then doFlag = 0
				If errorFlag = 0 And doFlag > 0 Then
					For i = 0 To dataPtr.triangleCount - 1
						Dim normal(8) As Single
						normal(0) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).x
						normal(1) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).y
						normal(2) = dataPtr.normal(dataPtr.triangle(i).normalIndex(0)).z

						normal(3) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).x
						normal(4) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).y
						normal(5) = dataPtr.normal(dataPtr.triangle(i).normalIndex(1)).z

						normal(6) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).x
						normal(7) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).y
						normal(8) = dataPtr.normal(dataPtr.triangle(i).normalIndex(2)).z

						Dim conPtr As Int32 = At3d_SetVertNorm_Face(i, layerName(0), normal(0), 0)

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					Next
				End If


				If errorFlag = 0 Then
					At3d_SetMaterial_I1(layerName(0), At3d_MatFlag.MATFLAG_I1_DXF_COLOR, dataPtr.dxfColor)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, dataPtr.ambientRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, dataPtr.diffuseRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, dataPtr.specularRGB.red)

					At3d_SetMaterial_F3(layerName(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, dataPtr.emissiveRGB.red)

					If dataPtr.texturePathName <> Nothing Then
						Dim texturePathName(MAX_PATH - 1) As Byte
						texturePathName = AE.GetBytes(dataPtr.texturePathName)

						At3d_SetTextureName(layerName(0), texturePathName(0))
					End If
				End If

				If errorFlag = 0 Then fileLoaded = 1
			End If

			If errorFlag > 0 Then
				Clear_All_Objects()
				Exit For
			End If
		Next

		If errorFlag = 0 Then
			At3d_TransferDone()

			' need a file name to open FileSaveDialog
			'
			inName = "BlueMonk.lwo"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)

	End Sub

	Public Sub TransferMultiMatKnightToDll()
		multiMatKnight = New CMultiMatKnight()

		' in case there is a 3D object in the DLL
		'
		Clear_All_Objects()

		' remember current setting for axis system
		' then set to AutoCAD axis system
		'
		Dim oldAxisFlag As Int32 = At3d_ReadFlag(At3d_LibFlag.LIBFLAG_APP_AXES)
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, 0)

		' MultiMatKnight has several layers and
		' one or more materials can be assigned to any layer
		'
		' if multiple materials are used on a layer, child layers will be created
		'
		' Create one layer for each material assigned to the layer
		' store the pointer to the layer that is created
		' copy the material data to the layer
		'
		' MultiMatKnight is an avatar so
		' a hierarchy will be created, tag numbers will be set and
		' the pivot point for the layer will be set
		'
		' the vertex coordinates and the pivot point as defined in the
		' world coordinate system
		'
		Dim materialCount As Int32 = multiMatKnight.materialCount
		Dim origLayerCount As Int32 = multiMatKnight.layerCount

		' determine if there are child layers
		' this example method to determine if there are child layers is inefficient
		' if the layer count or the triangle count is high
		'
		Dim errorFlag As Int32 = 0
		Dim layerList(origLayerCount - 1, materialCount - 1) As Int32
		Dim matPerLayer(origLayerCount - 1) As Int32
		Dim layerCount As Int32 = 0

		Dim dataPtr As CMultiMatKnight.TEST_3D_DATA5

		Dim name1(LEN_LAYER_NAME - 1) As Byte
		Dim name2(LEN_LAYER_NAME - 1) As Byte
		Dim textureName(MAX_PATH - 1) As Byte

		Dim i As Int32
		Dim j As Int32
		Dim k As Int32

		' Check layer and parentLayer names
		'
		For i = 0 To origLayerCount - 1
			dataPtr = multiMatKnight.data5(i)

			If dataPtr.name Is Nothing Then
				' do not check
			ElseIf dataPtr.name Is "" Then
				' do not check
			Else
				name1 = AE.GetBytes(dataPtr.name)
				At3d_CheckName(name1(0))
				dataPtr.name = AE.GetString(name1)
			End If

			If dataPtr.parentName Is Nothing Then
				' do not check
			ElseIf dataPtr.parentName Is "" Then
				' do not check
			Else
				name1 = AE.GetBytes(dataPtr.parentName)
				At3d_CheckName(name1(0))
				dataPtr.parentName = AE.GetString(name1)
			End If
		Next

		' Check material names
		'
		For j = 0 To materialCount - 1
			If multiMatKnight.dataMaterial(j).name Is Nothing Then
				' do not check
			ElseIf multiMatKnight.dataMaterial(j).name Is "" Then
				' do not check
			Else
				name1 = AE.GetBytes(multiMatKnight.dataMaterial(j).name)
				At3d_CheckName(name1(0))
				multiMatKnight.dataMaterial(j).name = AE.GetString(name1)
			End If
		Next

		' mark materials used on each layer
		'
		For i = 0 To origLayerCount - 1
			dataPtr = multiMatKnight.data5(i)

			Dim lastMatIndex As Int32 = -1

			For k = 0 To dataPtr.triangleCount - 1
				Dim matIndex As Int32 = dataPtr.triangle(k).materialIndex

				If matIndex <> lastMatIndex And _
				 matIndex > -1 And matIndex < materialCount Then
					layerList(i, matIndex) = 1
					lastMatIndex = matIndex
				End If
			Next
		Next

		' count number of materials used on each layer
		' a new layer will be created for each material and layer combination
		'
		For i = 0 To origLayerCount - 1
			For k = 0 To materialCount - 1
				If layerList(i, k) > 0 Then
					layerCount += 1
					matPerLayer(i) += 1
				End If
			Next
		Next

		' vertex, uv, normal coordinates and triangle data will be
		' copied to the same target layer
		'
		Dim targetName As String = Nothing

		' create layers
		'
		For i = 0 To origLayerCount - 1
			dataPtr = multiMatKnight.data5(i)

			Dim origName As String
			origName = dataPtr.name

			k = 0

			For j = 0 To materialCount - 1
				If layerList(i, j) > 0 Then
					Dim layerName As String

					If matPerLayer(i) > 1 Then
						' more than one material used on layer
						' there will be a parent and child layers
						' use original layer name plus material name for new layer name
						'
						layerName = origName + "_" + multiMatKnight.dataMaterial(j).name

						' this example does not check for duplicate names
						'
						Dim len As Int32 = layerName.Length
						If len > LEN_LAYER_NAME - 1 Then
							layerName.Remove(LEN_LAYER_NAME - 1, len - LEN_LAYER_NAME - 1)
						End If

						' name has changed so update it
						'
						If k = 0 Then
							' update parent name
							'
							Dim ii As Int32
							For ii = 0 To origLayerCount - 1
								If ii <> i And origName = multiMatKnight.data5(ii).parentName Then
									multiMatKnight.data5(ii).parentName = layerName
								End If
							Next

							' update layer name
							'
							dataPtr.name = layerName
						End If
					Else
						layerName = origName
					End If

					If targetName Is Nothing Then
						targetName = layerName
					End If

					' Create layer
					'
					name1 = AE.GetBytes(layerName)
					Dim layerPtr As Int32 = At3d_CreateLayer(name1(0))
					If layerPtr = 0 Then
						errorFlag += 1
						Exit For
					Else
						' save pointer to the layer
						'
						layerList(i, j) = layerPtr

						' properties can be set before or after
						' dividing the object into multiple objects
						'
						name1 = AE.GetBytes(layerName)

						At3d_SetMaterial_F3(name1(0), At3d_MatFlag.MATFLAG_F3_AMBIENT, multiMatKnight.dataMaterial(j).ambientRGB.red)

						At3d_SetMaterial_F3(name1(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, multiMatKnight.dataMaterial(j).diffuseRGB.red)

						At3d_SetMaterial_F3(name1(0), At3d_MatFlag.MATFLAG_F3_SPECULAR, multiMatKnight.dataMaterial(j).specularRGB.red)

						At3d_SetMaterial_F3(name1(0), At3d_MatFlag.MATFLAG_F3_EMISSIVE, multiMatKnight.dataMaterial(j).emissiveRGB.red)

						If multiMatKnight.dataMaterial(j).texturePathName.Length > 0 Then
							textureName = AE.GetBytes(multiMatKnight.dataMaterial(j).texturePathName)

							At3d_SetTextureName(name1(0), textureName(0))
						End If

						Dim tag As Int32 = 0
						If k = 0 Then tag = dataPtr.tag

						At3d_SetMaterial_I1(name1(0), At3d_MatFlag.MATFLAG_I1_RWX_CLUMPTAG, tag)

						k += 1

						' convert float to double before transfering
						'
						Dim xyz(2) As Double
						xyz(0) = dataPtr.pivotPoint.x
						xyz(1) = dataPtr.pivotPoint.y
						xyz(2) = dataPtr.pivotPoint.z

						At3d_SetLayerPivotPoint(name1(0), xyz(0))

						' set parent layer
						'
						If k > 1 Then
							name2 = AE.GetBytes(dataPtr.name)

							At3d_SetLayerParent(name1(0), name2(0))
						End If
					End If
				End If
			Next

			If errorFlag Then Exit For
		Next

		' just in case
		'
		For i = 0 To origLayerCount - 1
			For j = 0 To materialCount - 1
				If layerList(i, j) = 1 Then layerList(i, j) = 0
			Next
		Next

		' set parent layer
		'
		If errorFlag = 0 Then
			For i = 0 To origLayerCount - 1
				dataPtr = multiMatKnight.data5(i)

				name1 = AE.GetBytes(dataPtr.name)
				If dataPtr.parentName Is Nothing Then
					name2(0) = 0
				ElseIf dataPtr.parentName = "" Then
					name2(0) = 0
				Else
					name2 = AE.GetBytes(dataPtr.parentName)
				End If

				At3d_SetLayerParent(name1(0), name2(0))
			Next
		End If

		' get totals from all layers
		'
		Dim xyzTotal As Int32 = 0
		Dim uvTotal As Int32 = 0
		Dim normalTotal As Int32 = 0
		Dim triangleTotal As Int32 = 0
		If errorFlag = 0 Then
			For i = 0 To origLayerCount - 1
				dataPtr = multiMatKnight.data5(i)

				xyzTotal += dataPtr.xyzCount
				uvTotal += dataPtr.uvCount
				normalTotal += dataPtr.normalCount
				triangleTotal += dataPtr.triangleCount
			Next

			If xyzTotal = 0 Then errorFlag += 1
			If triangleTotal = 0 Then errorFlag += 1
		End If

		' transfer vertices
		'
		If errorFlag = 0 Then
			name1 = AE.GetBytes(targetName)
			If At3d_AllocVertexs(name1(0), xyzTotal) = 0 Then
				errorFlag += 1
			Else
				k = 0
				For i = 0 To origLayerCount - 1
					dataPtr = multiMatKnight.data5(i)

					For j = 0 To dataPtr.xyzCount - 1
						If k < xyzTotal Then
							Dim fvPtr As Int32 = 0

							' a float can be transferred as a float or a double
							'
							If vertexFloatTransferFlag Then
								fvPtr = At3d_SetFloatVertex(k, name1(0), dataPtr.xyz(j).x)
								k += 1
							Else
								' convert float to double before transferring
								'
								Dim xyz(2) As Double
								xyz(0) = dataPtr.xyz(j).x
								xyz(1) = dataPtr.xyz(j).y
								xyz(2) = dataPtr.xyz(j).z

								fvPtr = At3d_SetVertex(k, name1(0), xyz(0))
								k += 1
							End If

							If fvPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						End If
					Next

					If errorFlag Then Exit For
				Next
			End If
		End If

		' transfer faces
		'
		If errorFlag = 0 Then
			name1 = AE.GetBytes(targetName)
			If At3d_AllocFaces(name1(0), triangleTotal) = 0 Then
				errorFlag += 1
			Else
				Dim xyzOffset As Int32 = 0
				k = 0
				For i = 0 To origLayerCount - 1
					dataPtr = multiMatKnight.data5(i)

					For j = 0 To dataPtr.triangleCount - 1
						If k < triangleTotal Then
							Dim xyzIndex(2) As Int32
							xyzIndex(0) = dataPtr.triangle(j).xyzIndex(0) + xyzOffset
							xyzIndex(1) = dataPtr.triangle(j).xyzIndex(1) + xyzOffset
							xyzIndex(2) = dataPtr.triangle(j).xyzIndex(2) + xyzOffset

							Dim conPtr As Int32 = At3d_SetFace(k, name1(0), xyzIndex(0))
							k += 1

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						End If
					Next

					xyzOffset += dataPtr.xyzCount

					If errorFlag Then Exit For
				Next
			End If
		End If

		' transfer UV coordinates
		'
		If errorFlag = 0 And uvTotal Then
			name1 = AE.GetBytes(targetName)
			k = 0
			For i = 0 To origLayerCount - 1
				dataPtr = multiMatKnight.data5(i)

				If dataPtr.uv Is Nothing Then
					k += dataPtr.triangleCount
				Else
					For j = 0 To dataPtr.triangleCount - 1
						If k < triangleTotal Then
							Dim uv(5) As Single
							uv(0) = dataPtr.uv(dataPtr.triangle(j).uvIndex(0)).u
							uv(1) = dataPtr.uv(dataPtr.triangle(j).uvIndex(0)).v

							uv(2) = dataPtr.uv(dataPtr.triangle(j).uvIndex(1)).u
							uv(3) = dataPtr.uv(dataPtr.triangle(j).uvIndex(1)).v

							uv(4) = dataPtr.uv(dataPtr.triangle(j).uvIndex(2)).u
							uv(5) = dataPtr.uv(dataPtr.triangle(j).uvIndex(2)).v

							Dim conPtr As Int32 = At3d_SetUV_Face(k, name1(0), uv(0))
							k += 1

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						End If
					Next
				End If

				If errorFlag Then Exit For
			Next
		End If

		' transfer normals
		'
		If errorFlag = 0 And normalTotal Then
			name1 = AE.GetBytes(targetName)
			k = 0
			For i = 0 To origLayerCount - 1
				dataPtr = multiMatKnight.data5(i)

				If dataPtr.normal Is Nothing Then
					k += dataPtr.triangleCount
				Else
					For j = 0 To dataPtr.triangleCount - 1
						If k < triangleTotal Then
							Dim normal(8) As Single
							normal(0) = dataPtr.normal(dataPtr.triangle(j).normalIndex(0)).x
							normal(1) = dataPtr.normal(dataPtr.triangle(j).normalIndex(0)).y
							normal(2) = dataPtr.normal(dataPtr.triangle(j).normalIndex(0)).z

							normal(3) = dataPtr.normal(dataPtr.triangle(j).normalIndex(1)).x
							normal(4) = dataPtr.normal(dataPtr.triangle(j).normalIndex(1)).y
							normal(5) = dataPtr.normal(dataPtr.triangle(j).normalIndex(1)).z

							normal(6) = dataPtr.normal(dataPtr.triangle(j).normalIndex(2)).x
							normal(7) = dataPtr.normal(dataPtr.triangle(j).normalIndex(2)).y
							normal(8) = dataPtr.normal(dataPtr.triangle(j).normalIndex(2)).z

							Dim conPtr As Int32 = At3d_SetVertNorm_Face(k, name1(0), normal(0), 0)
							k += 1

							If conPtr = 0 Then
								errorFlag += 1
								Exit For
							End If
						End If
					Next
				End If

				If errorFlag Then Exit For
			Next
		End If

		' transfer layer pointers so that the polygon mesh data can
		' be moved to the correct layers
		'
		If errorFlag = 0 Then
			name1 = AE.GetBytes(targetName)
			k = 0
			For i = 0 To origLayerCount - 1
				dataPtr = multiMatKnight.data5(i)

				For j = 0 To dataPtr.triangleCount - 1

					Dim matIndex As Int32 = dataPtr.triangle(j).materialIndex

					If k < triangleTotal And _
					 matIndex > -1 And matIndex < materialCount Then
						Dim layerPtr As Int32 = layerList(i, matIndex)

						Dim conPtr As Int32 = At3d_SetFaceLayerPointer(k, name1(0), layerPtr)
						k += 1

						If conPtr = 0 Then
							errorFlag += 1
							Exit For
						End If
					End If
				Next

				If errorFlag Then Exit For
			Next
		End If

		If errorFlag = 0 Then fileLoaded = 1

		If errorFlag Then
			Clear_All_Objects()
		End If

		If errorFlag = 0 Then
			At3d_TransferDone()

			' move the polygon mesh data to the correct layers
			'
			name1 = AE.GetBytes(targetName)
			At3d_DivideFaceLayerPointers(name1(0))

			' when UV coordinates are transferred all layers
			' are marked as containing textures even if they do not
			' clear UV coordinates from layers that are not textured
			'
			If uvTotal Then
				Dim count As Int32 = At3d_LayerCount()
				If count Then
					Dim layer As Int32 = 0
					For i = 0 To count - 1
						layer = At3d_GetNextLayer(layer, name1(0))
						If layer Then
							At3d_GetTextureName(name1(0), textureName(0))

							If textureName(0) = 0 Then
								At3d_Remove_UV_Coordinates(name1(0))
							End If
						End If
					Next
				End If
			End If

			' need a file name to open FileSaveDialog
			'
			inName = "MultiMatKnight.lwo"
		End If

		' restore old axis system
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_APP_AXES, oldAxisFlag)
	End Sub

	Public Sub Create_UV_Coordinates()
		' this test will create UV coordinates on the first layer only
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32
		layer = At3d_GetNextLayer(0, name(0))
		If (layer) Then
			At3d_Set_UV_Transform(name(0), textureCenter(0), textureRotation, textureScale(0), textureTranslation(0))
			At3d_Create_UV_Coordinates(name(0), textureType(textureTypeIndex))
		End If
	End Sub

	Public Sub Remove_UV_Coordinates()
		' this test will remove UV coordinates on the first layer only
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32
		layer = At3d_GetNextLayer(0, name(0))
		If (layer) Then
			At3d_Remove_UV_Coordinates(name(0))
		End If
	End Sub

	Public Sub DivideTriangles(ByRef typeFlag As Integer)
		' this test will divide triangles on the first layer only
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32
		layer = At3d_GetNextLayer(0, name(0))
		If (layer) Then
			At3d_DivideTriangles(name(0), typeFlag)
		End If

	End Sub

	Public Sub WriteDemContourMap()
		If fileLoaded = 0 Or inName = Nothing Then
			bufferWriteFlag = 0
			Return
		End If

		Dim scaleFactor As Double = 1.0

		' get name
		'
		Dim name As String
		name = Path.GetFileNameWithoutExtension(inName)

		' get drive and dir
		'
		Dim path1 As String
		If outName = Nothing Then
			path1 = Path.GetDirectoryName(inName)
		Else
			path1 = Path.GetDirectoryName(outName)
		End If

		' construct output file name
		'
		name += ".bmp"

		Dim filter As String = "Contour Map"
		filter += "|*"
		filter += ".bmp"

		Dim dlg As New SaveFileDialog()

		dlg.InitialDirectory = path1
		dlg.Filter = filter
		dlg.FilterIndex = 1
		dlg.FileName = name
		dlg.CheckPathExists = True
		dlg.OverwritePrompt = True
		dlg.RestoreDirectory = True

		If dlg.ShowDialog() = DialogResult.OK Then
			outName = dlg.FileName
			Dim name1 As Byte() = AE.GetBytes(outName)
			At3d_WriteDemContourMap(name1(0), demSeaLevelFlag, demBelowFactor, demAboveFactor)
		End If

		bufferWriteFlag = 0
	End Sub

	Public Sub EraseLines1()
		' lines(2D) are deleted on all layers
		' any layers that do not contain meshes, lines or point clouds are deleted
		' and then the OpenGL view is updated
		'
		At3d_Erase_All_Lines()
	End Sub

	Public Sub EraseLines2()
		' lines(2D) are deleted on all layers
		' any layers that do not contain meshes, lines or point clouds are deleted
		' and then the OpenGL view is updated
		'
		' assume the app has not made a list of layer names so just get layer names
		' from DLL and use them
		'
		Dim name0(LEN_LAYER_NAME - 1) As Byte
		Dim name1(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32

		layer = At3d_GetNextLayer(0, name0(0))
		While layer
			' as the layer can be deleted get next layer before erasing
			'
			Array.Copy(name0, name1, LEN_LAYER_NAME)
			layer = At3d_GetNextLayer(layer, name0(0))

			At3d_Erase_Lines(name1(0))
		End While
	End Sub

	Public Sub EraseClouds1()
		' point clouds(1D) are deleted on all layers
		' any layers that do not contain meshes, lines or point clouds are deleted
		' and then the OpenGL view is updated
		'
		At3d_Erase_All_Clouds()
	End Sub

	Public Sub EraseClouds2()
		' point clouds(1D) are deleted on all layers
		' any layers that do not contain meshes, lines or point clouds are deleted
		' and then the OpenGL view is updated
		'
		' assume the app has not made a list of layer names so just get layer names
		' from DLL and use them
		'
		Dim name0(LEN_LAYER_NAME - 1) As Byte
		Dim name1(LEN_LAYER_NAME - 1) As Byte
		Dim layer As Int32

		layer = At3d_GetNextLayer(0, name0(0))
		While layer
			' as the layer can be deleted get next layer before erasing
			'
			Array.Copy(name0, name1, LEN_LAYER_NAME)
			layer = At3d_GetNextLayer(layer, name0(0))

			At3d_Erase_Clouds(name1(0))
		End While
	End Sub

	Public Sub WaterTightCheck()
        ' remove any layers from previous watertight check
		'
        At3d_Remove_Layers_Watertight_Check()

        ' check if meshes are watertight
		'
		Dim result As Int32
		Dim result1 As DialogResult
		Dim sharedFlag As Int32 = 0

        result = At3d_Check_For_Watertight_Meshes()

		If result = 1 Then
            MessageBox.Show("Meshes are watertight.", "Watertight Check", MessageBoxButtons.OK)
		ElseIf result = 2 Then
            result1 = MessageBox.Show("Meshes are watertight. Some edges are shared with 3 or more polygons.  Display edges shared with 3 or more polygons?", "Watertight Check", MessageBoxButtons.YesNo)

			If result1 = DialogResult.Yes Then
				At3d_Make_Edges_For_Shared_Edges_Layer()
			End If
		ElseIf result < 0 Then
			Dim msg As String
			If result = -1 Then
				msg = "Meshes have holes.  Display edges for holes?"
			Else
				msg = "Meshes have holes.  Some edges are shared with 3 or more polygons.  Display edges for holes and shared edges?"
				sharedFlag = 1
			End If

            result1 = MessageBox.Show(msg, "Watertight Check", MessageBoxButtons.YesNo)

			If result1 = DialogResult.Yes Then
				At3d_Make_Edges_For_Holes_Layer()

				If sharedFlag Then At3d_Make_Edges_For_Shared_Edges_Layer()
			End If
		End If
	End Sub

	Public Sub EditGetUpperBevels()
		Dim count As Int32
		count = At3d_Edit_Get_Bevel_Count(At3d_EditBevelType.EDIT_BEVELS_UPPER)

		If count > -1 Then
			upperBevelsCount = count

			If count > 0 Then
				' size of array is limited
				'
				If count > BEVELS_ARRAY_TOTAL Then
					count = BEVELS_ARRAY_TOTAL
					upperBevelsCount = BEVELS_ARRAY_TOTAL
				End If

				Dim i As Int32
				For i = 0 To count - 1
					At3d_Edit_Get_Bevel(At3d_EditBevelType.EDIT_BEVELS_UPPER, i, upperBevelsWidth(i), upperBevelsHeight(i))
				Next
			End If
		End If
	End Sub

	Public Sub EditSetUpperBevels()
		If upperBevelsCount > 0 Then
			'do not call if bevels are already clear
			'
			Dim count As Int32
			count = At3d_Edit_Get_Bevel_Count(At3d_EditBevelType.EDIT_BEVELS_UPPER)
			If count > 0 Then
				At3d_Edit_Clear_Bevels(At3d_EditBevelType.EDIT_BEVELS_UPPER)
			End If

			Dim i As Int32
			For i = 0 To upperBevelsCount - 1
				At3d_Edit_Set_Bevel(At3d_EditBevelType.EDIT_BEVELS_UPPER, i, upperBevelsWidth(i), upperBevelsHeight(i))
			Next
		End If
	End Sub

	Public Sub EditGetLowerBevels()
		Dim count As Int32
		count = At3d_Edit_Get_Bevel_Count(At3d_EditBevelType.EDIT_BEVELS_LOWER)

		If count > -1 Then
			lowerBevelsCount = count

			If count > 0 Then
				' size of array is limited
				'
				If count > BEVELS_ARRAY_TOTAL Then
					count = BEVELS_ARRAY_TOTAL
					lowerBevelsCount = BEVELS_ARRAY_TOTAL
				End If

				Dim i As Int32
				For i = 0 To count - 1
					At3d_Edit_Get_Bevel(At3d_EditBevelType.EDIT_BEVELS_LOWER, i, lowerBevelsWidth(i), lowerBevelsHeight(i))
				Next
			End If
		End If
	End Sub

	Public Sub EditSetLowerBevels()
		If lowerBevelsCount > 0 Then
			'do not call if bevels are already clear
			'
			Dim count As Int32
			count = At3d_Edit_Get_Bevel_Count(At3d_EditBevelType.EDIT_BEVELS_LOWER)
			If count > 0 Then
				At3d_Edit_Clear_Bevels(At3d_EditBevelType.EDIT_BEVELS_LOWER)
			End If

			Dim i As Int32
			For i = 0 To lowerBevelsCount - 1
				At3d_Edit_Set_Bevel(At3d_EditBevelType.EDIT_BEVELS_LOWER, i, lowerBevelsWidth(i), lowerBevelsHeight(i))
			Next
		End If
	End Sub

	Public Sub ApplyBevels1()
		' apply bevels from a premade bevel set
		'
		upperBevelsCount = 5

		upperBevelsWidth(0) = 0.0
		upperBevelsWidth(1) = 0.003
		upperBevelsWidth(2) = 0.003
		upperBevelsWidth(3) = 0.003
		upperBevelsWidth(4) = 0.0

		upperBevelsHeight(0) = 0.05
		upperBevelsHeight(1) = 0.003
		upperBevelsHeight(2) = 0.0
		upperBevelsHeight(3) = -0.003
		upperBevelsHeight(4) = -0.006

		' set for no drawing
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 1)

		' enter extrusion module
		'
		Dim result As Int32
		result = At3d_Extrude_Mouse()

		If result Then
			' select bevel set
			'
			If bevelSetsFlag And textName(0) > 0 Then
				At3d_Edit_Select_Bevel_Set(textName(0))
			End If

			' set upper bevels
			'
			EditSetUpperBevels()

			' clear lower bevels
			'
			At3d_Edit_Clear_Bevels(At3d_EditBevelType.EDIT_BEVELS_LOWER)

			' set flags
			'
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_UPPER_FACES, 1)
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_UPPER_BEVELS, 1)

			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_LOWER_FACES, 1)
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_LOWER_BEVELS, 0)

			' enable drawing
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)

			' do extrusion
			'
			At3d_Edit_Extrude_Now()

		Else
			' enable drawing
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)
		End If
	End Sub

	Public Sub ApplyBevels2()
		' apply bevels from a premade bevel set
		'
		upperBevelsCount = 5

		upperBevelsWidth(0) = 0.0
		upperBevelsWidth(1) = 0.003
		upperBevelsWidth(2) = 0.003
		upperBevelsWidth(3) = 0.003
		upperBevelsWidth(4) = 0.0

		upperBevelsHeight(0) = 0.05
		upperBevelsHeight(1) = 0.003
		upperBevelsHeight(2) = 0.0
		upperBevelsHeight(3) = -0.003
		upperBevelsHeight(4) = -0.03

		lowerBevelsCount = 2

		lowerBevelsWidth(0) = -0.008
		lowerBevelsWidth(1) = 0.0

		lowerBevelsHeight(0) = -0.009
		lowerBevelsHeight(1) = -0.02

		' set for no drawing
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 1)

		' enter extrusion module
		'
		Dim result As Int32
		result = At3d_Extrude_Mouse()

		If result Then
			' select bevel set
			'
			If bevelSetsFlag And textName(0) > 0 Then
				At3d_Edit_Select_Bevel_Set(textName(0))
			End If

			' set upper bevels
			'
			EditSetUpperBevels()

			' set lower bevels
			'
			EditSetLowerBevels()

			' set flags
			'
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_UPPER_FACES, 1)
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_UPPER_BEVELS, 1)

			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_LOWER_FACES, 1)
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_LOWER_BEVELS, 1)

			' enable drawing
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)

			' do extrusion
			'
			At3d_Edit_Extrude_Now()

		Else
			' enable drawing
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)
		End If
	End Sub

	Public Sub ApplyBevels3()
		' apply bevels from a premade bevel set
		'
		upperBevelsCount = 5

		upperBevelsWidth(0) = 0.0
		upperBevelsWidth(1) = 0.003
		upperBevelsWidth(2) = 0.003
		upperBevelsWidth(3) = 0.003
		upperBevelsWidth(4) = 0.0

		upperBevelsHeight(0) = 0.05
		upperBevelsHeight(1) = 0.003
		upperBevelsHeight(2) = 0.0
		upperBevelsHeight(3) = -0.003
		upperBevelsHeight(4) = -0.05

		lowerBevelsCount = 4

		lowerBevelsWidth(0) = -0.008
		lowerBevelsWidth(1) = 0.0
		lowerBevelsWidth(2) = 0.017
		lowerBevelsWidth(3) = 0.0

		lowerBevelsHeight(0) = -0.009
		lowerBevelsHeight(1) = -0.02
		lowerBevelsHeight(2) = 0.0
		lowerBevelsHeight(3) = 0.029

		' set for no drawing
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 1)

		' enter extrusion module
		'
		Dim result As Int32
		result = At3d_Extrude_Mouse()

		If result Then
			' select bevel set
			'
			If bevelSetsFlag And textName(0) > 0 Then
				At3d_Edit_Select_Bevel_Set(textName(0))
			End If

			' set upper bevels
			'
			EditSetUpperBevels()

			' set lower bevels
			'
			EditSetLowerBevels()

			' set flags
			'
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_UPPER_FACES, 0)
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_UPPER_BEVELS, 1)

			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_LOWER_FACES, 0)
			At3d_Edit_Set_Extrude_Flag(At3d_EditExtrudeFlags.EDIT_FLAG_LOWER_BEVELS, 1)

			' enable drawing
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)

			' do extrusion
			'
			At3d_Edit_Extrude_Now()

		Else
			' enable drawing
			'
			At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)
		End If
	End Sub

	Public Sub Text_MakeBevelSets()
		' set for no drawing
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 1)

		' enter extrusion module
		'
		Dim result As Int32
		result = At3d_Extrude_Mouse()

		If result Then
			' if there is more than one layer, create a bevel set for each layer
			' and copy the original bevel set to the new bevel sets
			'
			bevelSetsFlag = At3d_Edit_Make_Bevel_Sets()

			' do extrusion
			'
			At3d_Edit_Extrude_Now()
		End If

		' enable drawing
		'
		At3d_WriteFlag(At3d_LibFlag.LIBFLAG_NO_DRAW, 0)
	End Sub

	Public Sub GetStageImage()
		Dim path1 As String = "c:\"
		If stageImageName <> Nothing Then
			path1 = Path.GetDirectoryName(stageImageName)
		End If

		Dim filter As String
		filter = "Texture"
		filter += "|*"
		filter += "*.bmp;*.gif;*.iff;*.jpg;*.png;*.tga;*.tif"
		filter += "|All|*.*"

		Dim dlg As New OpenFileDialog()

		dlg.InitialDirectory = path1
		dlg.Filter = filter
		dlg.FilterIndex = 1
		dlg.CheckFileExists = True
		dlg.CheckPathExists = True
		dlg.RestoreDirectory = True

		If dlg.ShowDialog() = DialogResult.OK Then
			stageImageName = dlg.FileName

			Dim name1 As Byte() = AE.GetBytes(stageImageName)
			At3d_SetStageImage(name1(0))
		End If
	End Sub

	Public Sub StartReducePolygons()
		At3d_StartReducePolygons(1)

		' first layer in list is selected first for reducing polygons
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		reducePolygonsNextLayer = At3d_GetNextLayer(0, name(0))
		reducePolygonsName = AE.GetString(name)

		GetReducePolygonsLayerData()
	End Sub

	Public Sub SelectReducePolygonsLayer()
		' just select layers in order they are in list
		'
		Dim name(LEN_LAYER_NAME - 1) As Byte
		reducePolygonsNextLayer = At3d_GetNextLayer(reducePolygonsNextLayer, name(0))
		reducePolygonsName = AE.GetString(name)

		GetReducePolygonsLayerData()
	End Sub

	Public Sub GetReducePolygonsLayerData()
		Dim name As Byte() = AE.GetBytes(reducePolygonsName)

		At3d_GetReducePolygonsData(name(0), reducePolygonsVertices0, reducePolygonsTriangles0, reducePolygonsVertices1, reducePolygonsTriangles1)
	End Sub

	Public Sub DoReducePolygons()
		Dim name As Byte() = AE.GetBytes(reducePolygonsName)

		At3d_SetReducePolygonsNumber(name(0), reducePolygonsVertices1)

		GetReducePolygonsLayerData()
	End Sub

	Public Sub GetBackgroundImage()
		Dim path1 As String = "c:\"
		If backgroundImageName <> Nothing Then
			path1 = Path.GetDirectoryName(backgroundImageName)
		End If

		Dim filter As String
		filter = "Image"
		filter += "|*"
		filter += "*.bmp;*.gif;*.iff;*.jpg;*.png;*.tga;*.tif"
		filter += "|All|*.*"

		Dim dlg As New OpenFileDialog()

		dlg.InitialDirectory = path1
		dlg.Filter = filter
		dlg.FilterIndex = 1
		dlg.CheckFileExists = True
		dlg.CheckPathExists = True
		dlg.RestoreDirectory = True

		If dlg.ShowDialog() = DialogResult.OK Then
			backgroundImageName = dlg.FileName

			Dim name1 As Byte() = AE.GetBytes(backgroundImageName)
			At3d_SetBackgroundImage(name1(0))
		End If
	End Sub

    Public Sub Calculate_DMS(ByVal location As Double, ByRef degreesPtr As Int32, ByRef minutesPtr As Int32, ByRef secondsPtr As Double, ByRef signPtr As Int32)
        If location < 0.0 Then
            signPtr = 1
        Else
            signPtr = 0
        End If

        Dim value As Double = Math.Abs(location)

        degreesPtr = Math.Floor(value)

        Dim fraction As Double = (value - Math.Floor(value)) * 60.0
        minutesPtr = Math.Floor(fraction)

        secondsPtr = (fraction - Math.Floor(fraction)) * 60.0
    End Sub

	Public Function Combine_DMS(ByVal degrees As Int32, ByVal minutes As Int32, ByVal seconds As Double, ByVal sign As Int32) As Double
		Dim mins As Double = minutes

		Dim totalSeconds As Double = Math.Abs(mins) * 60.0 + Math.Abs(seconds)

		Dim value As Double = Math.Abs(degrees) + totalSeconds / 3600.0

		If sign Then
			value *= -1.0
		End If

		Return value
  End Function

  Public Sub Get_KML_Data_From_DLL()
    Dim destName(99) As Byte
    Dim destDescription(199) As Byte

    Dim lengthDestName As Int32 = 100
    Dim lengthDestDescription As Int32 = 200

    Dim lengthSrcName As Int32 = 0
    Dim lengthSrcDescription As Int32 = 0

    Dim result As Int32
    result = At3d_Get_KML_Length_Folder(lengthSrcName, lengthSrcDescription)

    Dim doFlag As Integer = 1

    If result Then
      If lengthSrcName > lengthDestName Then doFlag = 0
      If lengthSrcDescription > lengthDestDescription Then doFlag = 0

      If doFlag Then
        result = At3d_Get_KML_Folder(destName(0), lengthDestName, destDescription(0), lengthDestDescription)

        If result Then
          kmlFolderName = AE.GetString(destName)
          kmlFolderDescription = AE.GetString(destDescription)
        End If
      End If
    End If

    ' --

    result = At3d_Get_KML_Length_Placemark(lengthSrcName, lengthSrcDescription)

    doFlag = 1

    If result Then
      If lengthSrcName > lengthDestName Then doFlag = 0
      If lengthSrcDescription > lengthDestDescription Then doFlag = 0

      If doFlag Then
        result = At3d_Get_KML_Placemark(destName(0), lengthDestName, destDescription(0), lengthDestDescription)

        If result Then
          kmlPlacemarkName = AE.GetString(destName)
          kmlPlacemarkDescription = AE.GetString(destDescription)
        End If
      End If
    End If

    ' --

    Dim kmlLookAt_Latitude As Double = 0.0
    Dim kmlLookAt_Longitude As Double = 0.0

    At3d_Get_KML_LookAt(kmlLookAt_Latitude, kmlLookAt_Longitude, kmlLookAt_Altitude, kmlLookAt_Altitude_Mode_Flag, kmlLookAt_Heading, kmlLookAt_Tilt, kmlLookAt_Range)

    Calculate_DMS(kmlLookAt_Latitude, kmlLookAt_Latitude_Degrees, kmlLookAt_Latitude_Minutes, kmlLookAt_Latitude_Seconds, kmlLookAt_Latitude_Sign)

    Calculate_DMS(kmlLookAt_Longitude, kmlLookAt_Longitude_Degrees, kmlLookAt_Longitude_Minutes, kmlLookAt_Longitude_Seconds, kmlLookAt_Longitude_Sign)

    ' --

    Dim kmlModel_Latitude As Double = 0.0
    Dim kmlModel_Longitude As Double = 0.0

    At3d_Get_KML_Model(kmlModel_Latitude, kmlModel_Longitude, kmlModel_Altitude, kmlModel_Altitude_Mode_Flag, kmlModel_Heading, kmlModel_Tilt, kmlModel_Roll, kmlModel_Scale_X, kmlModel_Scale_Y, kmlModel_Scale_Z)

    Calculate_DMS(kmlModel_Latitude, kmlModel_Latitude_Degrees, kmlModel_Latitude_Minutes, kmlModel_Latitude_Seconds, kmlModel_Latitude_Sign)

    Calculate_DMS(kmlModel_Longitude, kmlModel_Longitude_Degrees, kmlModel_Longitude_Minutes, kmlModel_Longitude_Seconds, kmlModel_Longitude_Sign)

    ' --

    Dim nameModelsFolder(LEN_FILE_FNAME - 1) As Byte
    Dim nameImagesFolder(LEN_FILE_FNAME - 1) As Byte

    At3d_Get_KML_ModelImage_Folders(kmlUseModelsFolderFlag, nameModelsFolder(0), kmlUseImagesFolderFlag, nameImagesFolder(0))
    kmlModelsFolderName = AE.GetString(nameModelsFolder)
    kmlImagesFolderName = AE.GetString(nameImagesFolder)
  End Sub

  Public Sub Transfer_2D_Outlines(ByVal flag As Int32)
    If flag < 1 Or flag > 3 Then
      Return
    End If

    ' in case there is a 3D object in the DLL
    '
    Clear_All_Objects()

    Dim errorFlag As Int32 = 0

    If flag = 1 Or flag = 3 Then
      Dim layerName1(LEN_LAYER_NAME - 1) As Byte
      layerName1 = AE.GetBytes("Shape1")
      At3d_CheckName(layerName1(0))

      Dim shapeDiffuseRGB1 As RGB = New RGB(1.0, 1.0, 1.0)

      Dim xyzArray1() As XYZ = New XYZ() { _
       New XYZ(0.0, 0.0, 0.0), _
       New XYZ(1.0, 0.0, 0.0), _
       New XYZ(1.0, 1.0, 0.0), _
       New XYZ(0.0, 1.0, 0.0) _
      }

      Dim count1 As Int32 = 4
      Dim closedFlag1 As Int32 = 1

      ' create layer
      '
      If At3d_CreateLayer(layerName1(0)) = 0 Then
        errorFlag = 1
      Else
        At3d_SetMaterial_F3(layerName1(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, shapeDiffuseRGB1.red)

        If At3d_Set_2D_Outline(layerName1(0), count1, xyzArray1(0).x, closedFlag1) = 0 Then
          errorFlag = 1
        End If
      End If
    End If

    If errorFlag = 0 Then
      If flag = 2 Or flag = 3 Then
        Dim layerName2(LEN_LAYER_NAME - 1) As Byte
        layerName2 = AE.GetBytes("Shape2")
        At3d_CheckName(layerName2(0))

        Dim shapeDiffuseRGB2 As RGB = New RGB(1.0, 1.0, 0.0)

        Dim xyzArray2a() As XYZ = New XYZ() { _
        New XYZ(2.2, 0.0, 0.0), _
         New XYZ(2.2, 1.0, 0.0), _
         New XYZ(1.2, 1.0, 0.0), _
         New XYZ(1.7, 0.8, 0.0), _
         New XYZ(2.0, 0.6, 0.0), _
         New XYZ(1.4, 0.5, 0.0), _
         New XYZ(1.6, 0.4, 0.0), _
         New XYZ(1.9, 0.4, 0.0), _
         New XYZ(1.9, 0.2, 0.0), _
         New XYZ(1.6, 0.2, 0.0), _
         New XYZ(1.6, 0.4, 0.0), _
         New XYZ(1.4, 0.5, 0.0), _
         New XYZ(1.7, 0.8, 0.0), _
         New XYZ(1.2, 1.0, 0.0), _
         New XYZ(1.2, 0.0, 0.0) _
        }

        Dim xyzArray2b() As FLOAT_XYZ = New FLOAT_XYZ() { _
        New FLOAT_XYZ(2.4, 0.0, 1.0), _
         New FLOAT_XYZ(3.4, 0.0, 1.0), _
         New FLOAT_XYZ(3.4, 0.2, 1.0), _
         New FLOAT_XYZ(3.1, 0.4, 1.0), _
         New FLOAT_XYZ(3.1, 0.6, 1.0), _
         New FLOAT_XYZ(3.4, 0.8, 1.0), _
         New FLOAT_XYZ(3.4, 1.0, 1.0), _
         New FLOAT_XYZ(2.4, 1.0, 1.0), _
         New FLOAT_XYZ(2.4, 0.8, 1.0), _
         New FLOAT_XYZ(2.7, 0.6, 1.0), _
         New FLOAT_XYZ(2.7, 0.4, 1.0), _
         New FLOAT_XYZ(2.4, 0.2, 1.0) _
        }

        Dim count2a As Int32 = 15
        Dim count2b As Int32 = 12
        Dim closedFlag2a As Int32 = 1
        Dim closedFlag2b As Int32 = 0

        ' create layer
        '
        If At3d_CreateLayer(layerName2(0)) = 0 Then
          errorFlag = 1
        Else
          At3d_SetMaterial_F3(layerName2(0), At3d_MatFlag.MATFLAG_F3_DIFFUSE, shapeDiffuseRGB2.red)

          If At3d_Set_2D_Outline(layerName2(0), count2a, xyzArray2a(0).x, closedFlag2a) = 0 Then
            errorFlag = 1
          End If

          If errorFlag = 0 Then
            If At3d_Set_2D_FloatOutline(layerName2(0), count2b, xyzArray2b(0).x, closedFlag2b) = 0 Then
              errorFlag = 1
            End If
          End If
        End If
      End If
    End If

    If errorFlag Then
      Clear_All_Objects()
    Else
      fileLoaded = At3d_Transfer_2D_Outline_Done(0.25)
    End If
  End Sub
End Class

