Merged changes in the trunk up to revision 48893.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Fri, 13 Jul 2012 23:23:06 +0000 (23:23 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Fri, 13 Jul 2012 23:23:06 +0000 (23:23 +0000)
Conflicts resolved:
source/blender/blenkernel/CMakeLists.txt
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/anim_filter.c
source/blender/makesrna/RNA_enum_types.h

621 files changed:
doc/python_api/rst/bge.types.rst
intern/cycles/bvh/bvh.cpp
intern/cycles/util/util_cache.cpp
intern/cycles/util/util_path.cpp
intern/ghost/intern/GHOST_SystemX11.cpp
intern/ghost/intern/GHOST_SystemX11.h
intern/ghost/intern/GHOST_WindowCocoa.mm
intern/ghost/intern/GHOST_WindowX11.cpp
intern/ghost/intern/GHOST_WindowX11.h
intern/guardedalloc/MEM_guardedalloc.h
intern/guardedalloc/intern/mallocn.c
intern/memutil/MEM_CacheLimiter.h
intern/memutil/MEM_CacheLimiterC-Api.h
intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
intern/raskter/CMakeLists.txt
intern/raskter/raskter.c
intern/raskter/raskter.h
intern/raskter/raskter_kdtree.c [new file with mode: 0644]
intern/raskter/raskter_kdtree.h [new file with mode: 0644]
intern/raskter/raskter_mt.c [new file with mode: 0644]
release/scripts/modules/bl_i18n_utils/bl_process_msg.py
release/scripts/modules/bl_i18n_utils/check_po.py
release/scripts/modules/bl_i18n_utils/clean_po.py
release/scripts/modules/bl_i18n_utils/import_po_from_branches.py
release/scripts/modules/bl_i18n_utils/merge_po.py
release/scripts/modules/bl_i18n_utils/rtl_preprocess.py
release/scripts/modules/bl_i18n_utils/settings.py
release/scripts/modules/bl_i18n_utils/update_branches.py
release/scripts/modules/bl_i18n_utils/update_mo.py
release/scripts/modules/bl_i18n_utils/update_msg.py
release/scripts/modules/bl_i18n_utils/update_po.py
release/scripts/modules/bl_i18n_utils/update_pot.py
release/scripts/modules/bl_i18n_utils/update_trunk.py
release/scripts/modules/bl_i18n_utils/utils.py
release/scripts/startup/bl_operators/wm.py
release/scripts/startup/bl_ui/properties_data_mesh.py
release/scripts/startup/bl_ui/space_clip.py
release/scripts/startup/bl_ui/space_info.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/startup/bl_ui/space_view3d.py
release/text/readme.html
source/blender/avi/intern/avi.c
source/blender/blenfont/BLF_api.h
source/blender/blenfont/BLF_translation.h
source/blender/blenfont/intern/blf.c
source/blender/blenfont/intern/blf_font.c
source/blender/blenfont/intern/blf_internal.h
source/blender/blenfont/intern/blf_lang.c
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_idprop.h
source/blender/blenkernel/BKE_lamp.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_mask.h
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/intern/CCGSubSurf.c
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/action.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/bmfont.c
source/blender/blenkernel/intern/booleanops_mesh.c
source/blender/blenkernel/intern/brush.c
source/blender/blenkernel/intern/bvhutils.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/colortools.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/customdata.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/fcurve.c
source/blender/blenkernel/intern/fmodifier.c
source/blender/blenkernel/intern/font.c
source/blender/blenkernel/intern/idprop.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/lamp.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/mask.c
source/blender/blenkernel/intern/mask_rasterize.c [new file with mode: 0644]
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/movieclip.c
source/blender/blenkernel/intern/nla.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/packedFile.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/property.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/seqcache.c
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/shrinkwrap.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenkernel/intern/writeframeserver.c
source/blender/blenlib/BLI_kdopbvh.h
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/BLI_rect.h
source/blender/blenlib/BLI_scanfill.h
source/blender/blenlib/BLI_string.h
source/blender/blenlib/BLI_threads.h
source/blender/blenlib/intern/BLI_ghash.c
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/blenlib/intern/DLRB_tree.c
source/blender/blenlib/intern/fileops.c
source/blender/blenlib/intern/freetypefont.c
source/blender/blenlib/intern/math_color_inline.c
source/blender/blenlib/intern/math_geom.c
source/blender/blenlib/intern/math_matrix.c
source/blender/blenlib/intern/math_rotation.c
source/blender/blenlib/intern/noise.c
source/blender/blenlib/intern/rct.c
source/blender/blenlib/intern/string.c
source/blender/blenlib/intern/threads.c
source/blender/blenlib/intern/voronoi.c
source/blender/blenlib/intern/voxel.c
source/blender/blenlib/intern/winstuff.c
source/blender/blenloader/intern/readfile.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/collada/EffectExporter.cpp
source/blender/collada/ImageExporter.cpp
source/blender/compositor/CMakeLists.txt
source/blender/compositor/COM_compositor.h
source/blender/compositor/intern/COM_CPUDevice.cpp
source/blender/compositor/intern/COM_Converter.cpp
source/blender/compositor/intern/COM_ExecutionGroup.cpp
source/blender/compositor/intern/COM_ExecutionSystem.cpp
source/blender/compositor/intern/COM_MemoryBuffer.cpp
source/blender/compositor/intern/COM_MemoryBuffer.h
source/blender/compositor/intern/COM_NodeOperation.cpp
source/blender/compositor/intern/COM_NodeOperation.h
source/blender/compositor/intern/COM_OpenCLDevice.cpp
source/blender/compositor/intern/COM_OpenCLDevice.h
source/blender/compositor/intern/COM_SingleThreadedNodeOperation.cpp
source/blender/compositor/intern/COM_SingleThreadedNodeOperation.h
source/blender/compositor/intern/COM_SocketReader.h
source/blender/compositor/intern/COM_WorkScheduler.cpp
source/blender/compositor/nodes/COM_BokehBlurNode.cpp
source/blender/compositor/nodes/COM_DefocusNode.cpp
source/blender/compositor/nodes/COM_DirectionalBlurNode.cpp
source/blender/compositor/nodes/COM_KeyingNode.cpp
source/blender/compositor/nodes/COM_KeyingNode.h
source/blender/compositor/nodes/COM_MathNode.cpp
source/blender/compositor/nodes/COM_MixNode.cpp
source/blender/compositor/nodes/COM_MovieClipNode.cpp
source/blender/compositor/nodes/COM_TrackPositionNode.cpp [new file with mode: 0644]
source/blender/compositor/nodes/COM_TrackPositionNode.h [new file with mode: 0644]
source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp
source/blender/compositor/operations/COM_AlphaOverKeyOperation.h
source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp
source/blender/compositor/operations/COM_AlphaOverMixedOperation.h
source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp
source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.h
source/blender/compositor/operations/COM_AntiAliasOperation.cpp
source/blender/compositor/operations/COM_AntiAliasOperation.h
source/blender/compositor/operations/COM_BilateralBlurOperation.cpp
source/blender/compositor/operations/COM_BilateralBlurOperation.h
source/blender/compositor/operations/COM_BlurBaseOperation.cpp
source/blender/compositor/operations/COM_BlurBaseOperation.h
source/blender/compositor/operations/COM_BokehBlurOperation.cpp
source/blender/compositor/operations/COM_BokehBlurOperation.h
source/blender/compositor/operations/COM_BokehImageOperation.cpp
source/blender/compositor/operations/COM_BokehImageOperation.h
source/blender/compositor/operations/COM_BoxMaskOperation.cpp
source/blender/compositor/operations/COM_BoxMaskOperation.h
source/blender/compositor/operations/COM_BrightnessOperation.cpp
source/blender/compositor/operations/COM_BrightnessOperation.h
source/blender/compositor/operations/COM_CalculateMeanOperation.cpp
source/blender/compositor/operations/COM_CalculateMeanOperation.h
source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp
source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.h
source/blender/compositor/operations/COM_ChangeHSVOperation.cpp
source/blender/compositor/operations/COM_ChangeHSVOperation.h
source/blender/compositor/operations/COM_ChannelMatteOperation.cpp
source/blender/compositor/operations/COM_ChannelMatteOperation.h
source/blender/compositor/operations/COM_ChromaMatteOperation.cpp
source/blender/compositor/operations/COM_ChromaMatteOperation.h
source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp
source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.h
source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp
source/blender/compositor/operations/COM_ColorBalanceLGGOperation.h
source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp
source/blender/compositor/operations/COM_ColorCorrectionOperation.h
source/blender/compositor/operations/COM_ColorCurveOperation.cpp
source/blender/compositor/operations/COM_ColorCurveOperation.h
source/blender/compositor/operations/COM_ColorMatteOperation.cpp
source/blender/compositor/operations/COM_ColorMatteOperation.h
source/blender/compositor/operations/COM_ColorRampOperation.cpp
source/blender/compositor/operations/COM_ColorRampOperation.h
source/blender/compositor/operations/COM_ColorSpillOperation.cpp
source/blender/compositor/operations/COM_ColorSpillOperation.h
source/blender/compositor/operations/COM_CombineChannelsOperation.cpp
source/blender/compositor/operations/COM_CombineChannelsOperation.h
source/blender/compositor/operations/COM_CompositorOperation.cpp
source/blender/compositor/operations/COM_CompositorOperation.h
source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp
source/blender/compositor/operations/COM_ConvertColorProfileOperation.h
source/blender/compositor/operations/COM_ConvertColorToBWOperation.cpp
source/blender/compositor/operations/COM_ConvertColorToBWOperation.h
source/blender/compositor/operations/COM_ConvertColorToValueProg.cpp
source/blender/compositor/operations/COM_ConvertColorToValueProg.h
source/blender/compositor/operations/COM_ConvertColorToVectorOperation.cpp
source/blender/compositor/operations/COM_ConvertColorToVectorOperation.h
source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp
source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.h
source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.cpp
source/blender/compositor/operations/COM_ConvertHSVToRGBOperation.h
source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.cpp
source/blender/compositor/operations/COM_ConvertKeyToPremulOperation.h
source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.cpp
source/blender/compositor/operations/COM_ConvertPremulToKeyOperation.h
source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.cpp
source/blender/compositor/operations/COM_ConvertRGBToHSVOperation.h
source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.cpp
source/blender/compositor/operations/COM_ConvertRGBToYCCOperation.h
source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.cpp
source/blender/compositor/operations/COM_ConvertRGBToYUVOperation.h
source/blender/compositor/operations/COM_ConvertValueToColorProg.cpp
source/blender/compositor/operations/COM_ConvertValueToColorProg.h
source/blender/compositor/operations/COM_ConvertValueToVectorOperation.cpp
source/blender/compositor/operations/COM_ConvertValueToVectorOperation.h
source/blender/compositor/operations/COM_ConvertVectorToColorOperation.cpp
source/blender/compositor/operations/COM_ConvertVectorToColorOperation.h
source/blender/compositor/operations/COM_ConvertVectorToValueOperation.cpp
source/blender/compositor/operations/COM_ConvertVectorToValueOperation.h
source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.cpp
source/blender/compositor/operations/COM_ConvertYCCToRGBOperation.h
source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.cpp
source/blender/compositor/operations/COM_ConvertYUVToRGBOperation.h
source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp
source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.h
source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp
source/blender/compositor/operations/COM_ConvolutionFilterOperation.h
source/blender/compositor/operations/COM_CropOperation.cpp
source/blender/compositor/operations/COM_CropOperation.h
source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp
source/blender/compositor/operations/COM_DifferenceMatteOperation.h
source/blender/compositor/operations/COM_DilateErodeOperation.cpp
source/blender/compositor/operations/COM_DilateErodeOperation.h
source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp
source/blender/compositor/operations/COM_DirectionalBlurOperation.h
source/blender/compositor/operations/COM_DisplaceOperation.cpp
source/blender/compositor/operations/COM_DisplaceOperation.h
source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp
source/blender/compositor/operations/COM_DisplaceSimpleOperation.h
source/blender/compositor/operations/COM_DistanceMatteOperation.cpp
source/blender/compositor/operations/COM_DistanceMatteOperation.h
source/blender/compositor/operations/COM_DotproductOperation.cpp
source/blender/compositor/operations/COM_DotproductOperation.h
source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp
source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.h
source/blender/compositor/operations/COM_EllipseMaskOperation.cpp
source/blender/compositor/operations/COM_EllipseMaskOperation.h
source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp
source/blender/compositor/operations/COM_FastGaussianBlurOperation.h
source/blender/compositor/operations/COM_FlipOperation.cpp
source/blender/compositor/operations/COM_FlipOperation.h
source/blender/compositor/operations/COM_GammaCorrectOperation.cpp
source/blender/compositor/operations/COM_GammaCorrectOperation.h
source/blender/compositor/operations/COM_GammaOperation.cpp
source/blender/compositor/operations/COM_GammaOperation.h
source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianAlphaXBlurOperation.h
source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianAlphaYBlurOperation.h
source/blender/compositor/operations/COM_GaussianBokehBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianBokehBlurOperation.h
source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianXBlurOperation.h
source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
source/blender/compositor/operations/COM_GaussianYBlurOperation.h
source/blender/compositor/operations/COM_GlareBaseOperation.cpp
source/blender/compositor/operations/COM_GlareBaseOperation.h
source/blender/compositor/operations/COM_GlareFogGlowOperation.cpp
source/blender/compositor/operations/COM_GlareThresholdOperation.cpp
source/blender/compositor/operations/COM_GlareThresholdOperation.h
source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp
source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.h
source/blender/compositor/operations/COM_IDMaskOperation.cpp
source/blender/compositor/operations/COM_IDMaskOperation.h
source/blender/compositor/operations/COM_ImageOperation.cpp
source/blender/compositor/operations/COM_ImageOperation.h
source/blender/compositor/operations/COM_InvertOperation.cpp
source/blender/compositor/operations/COM_InvertOperation.h
source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
source/blender/compositor/operations/COM_KeyingBlurOperation.h
source/blender/compositor/operations/COM_KeyingClipOperation.cpp
source/blender/compositor/operations/COM_KeyingClipOperation.h
source/blender/compositor/operations/COM_KeyingDespillOperation.cpp
source/blender/compositor/operations/COM_KeyingDespillOperation.h
source/blender/compositor/operations/COM_KeyingOperation.cpp
source/blender/compositor/operations/COM_KeyingOperation.h
source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
source/blender/compositor/operations/COM_KeyingScreenOperation.h
source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp
source/blender/compositor/operations/COM_LuminanceMatteOperation.h
source/blender/compositor/operations/COM_MapUVOperation.cpp
source/blender/compositor/operations/COM_MapUVOperation.h
source/blender/compositor/operations/COM_MapValueOperation.cpp
source/blender/compositor/operations/COM_MapValueOperation.h
source/blender/compositor/operations/COM_MaskOperation.cpp
source/blender/compositor/operations/COM_MaskOperation.h
source/blender/compositor/operations/COM_MathBaseOperation.cpp
source/blender/compositor/operations/COM_MathBaseOperation.h
source/blender/compositor/operations/COM_MixAddOperation.cpp
source/blender/compositor/operations/COM_MixAddOperation.h
source/blender/compositor/operations/COM_MixBaseOperation.cpp
source/blender/compositor/operations/COM_MixBaseOperation.h
source/blender/compositor/operations/COM_MixBlendOperation.cpp
source/blender/compositor/operations/COM_MixBlendOperation.h
source/blender/compositor/operations/COM_MixBurnOperation.cpp
source/blender/compositor/operations/COM_MixBurnOperation.h
source/blender/compositor/operations/COM_MixColorOperation.cpp
source/blender/compositor/operations/COM_MixColorOperation.h
source/blender/compositor/operations/COM_MixDarkenOperation.cpp
source/blender/compositor/operations/COM_MixDarkenOperation.h
source/blender/compositor/operations/COM_MixDifferenceOperation.cpp
source/blender/compositor/operations/COM_MixDifferenceOperation.h
source/blender/compositor/operations/COM_MixDivideOperation.cpp
source/blender/compositor/operations/COM_MixDivideOperation.h
source/blender/compositor/operations/COM_MixDodgeOperation.cpp
source/blender/compositor/operations/COM_MixDodgeOperation.h
source/blender/compositor/operations/COM_MixGlareOperation.cpp
source/blender/compositor/operations/COM_MixGlareOperation.h
source/blender/compositor/operations/COM_MixHueOperation.cpp
source/blender/compositor/operations/COM_MixHueOperation.h
source/blender/compositor/operations/COM_MixLightenOperation.cpp
source/blender/compositor/operations/COM_MixLightenOperation.h
source/blender/compositor/operations/COM_MixLinearLightOperation.cpp
source/blender/compositor/operations/COM_MixLinearLightOperation.h
source/blender/compositor/operations/COM_MixMultiplyOperation.cpp
source/blender/compositor/operations/COM_MixMultiplyOperation.h
source/blender/compositor/operations/COM_MixOverlayOperation.cpp
source/blender/compositor/operations/COM_MixOverlayOperation.h
source/blender/compositor/operations/COM_MixSaturationOperation.cpp
source/blender/compositor/operations/COM_MixSaturationOperation.h
source/blender/compositor/operations/COM_MixScreenOperation.cpp
source/blender/compositor/operations/COM_MixScreenOperation.h
source/blender/compositor/operations/COM_MixSoftLightOperation.cpp
source/blender/compositor/operations/COM_MixSoftLightOperation.h
source/blender/compositor/operations/COM_MixSubtractOperation.cpp
source/blender/compositor/operations/COM_MixSubtractOperation.h
source/blender/compositor/operations/COM_MixValueOperation.cpp
source/blender/compositor/operations/COM_MixValueOperation.h
source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp
source/blender/compositor/operations/COM_MovieClipAttributeOperation.h
source/blender/compositor/operations/COM_MovieClipOperation.cpp
source/blender/compositor/operations/COM_MovieClipOperation.h
source/blender/compositor/operations/COM_MovieDistortionOperation.cpp
source/blender/compositor/operations/COM_MovieDistortionOperation.h
source/blender/compositor/operations/COM_MultilayerImageOperation.cpp
source/blender/compositor/operations/COM_MultilayerImageOperation.h
source/blender/compositor/operations/COM_NormalizeOperation.cpp
source/blender/compositor/operations/COM_NormalizeOperation.h
source/blender/compositor/operations/COM_OpenCLKernels.cl
source/blender/compositor/operations/COM_OpenCLKernels.cl.h
source/blender/compositor/operations/COM_OutputFileOperation.cpp
source/blender/compositor/operations/COM_OutputFileOperation.h
source/blender/compositor/operations/COM_PreviewOperation.cpp
source/blender/compositor/operations/COM_PreviewOperation.h
source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp
source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.h
source/blender/compositor/operations/COM_ReadBufferOperation.cpp
source/blender/compositor/operations/COM_ReadBufferOperation.h
source/blender/compositor/operations/COM_RenderLayersAlphaProg.cpp
source/blender/compositor/operations/COM_RenderLayersAlphaProg.h
source/blender/compositor/operations/COM_RenderLayersBaseProg.cpp
source/blender/compositor/operations/COM_RenderLayersBaseProg.h
source/blender/compositor/operations/COM_RotateOperation.cpp
source/blender/compositor/operations/COM_RotateOperation.h
source/blender/compositor/operations/COM_ScaleOperation.cpp
source/blender/compositor/operations/COM_ScaleOperation.h
source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp
source/blender/compositor/operations/COM_ScreenLensDistortionOperation.h
source/blender/compositor/operations/COM_SeparateChannelOperation.cpp
source/blender/compositor/operations/COM_SeparateChannelOperation.h
source/blender/compositor/operations/COM_SetAlphaOperation.cpp
source/blender/compositor/operations/COM_SetAlphaOperation.h
source/blender/compositor/operations/COM_SetColorOperation.cpp
source/blender/compositor/operations/COM_SetColorOperation.h
source/blender/compositor/operations/COM_SetSamplerOperation.cpp
source/blender/compositor/operations/COM_SetSamplerOperation.h
source/blender/compositor/operations/COM_SetValueOperation.cpp
source/blender/compositor/operations/COM_SetValueOperation.h
source/blender/compositor/operations/COM_SetVectorOperation.cpp
source/blender/compositor/operations/COM_SetVectorOperation.h
source/blender/compositor/operations/COM_SocketProxyOperation.cpp
source/blender/compositor/operations/COM_SocketProxyOperation.h
source/blender/compositor/operations/COM_SplitViewerOperation.cpp
source/blender/compositor/operations/COM_SplitViewerOperation.h
source/blender/compositor/operations/COM_TextureOperation.cpp
source/blender/compositor/operations/COM_TextureOperation.h
source/blender/compositor/operations/COM_TonemapOperation.cpp
source/blender/compositor/operations/COM_TonemapOperation.h
source/blender/compositor/operations/COM_TrackPositionOperation.cpp [new file with mode: 0644]
source/blender/compositor/operations/COM_TrackPositionOperation.h [new file with mode: 0644]
source/blender/compositor/operations/COM_TranslateOperation.cpp
source/blender/compositor/operations/COM_TranslateOperation.h
source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.h
source/blender/compositor/operations/COM_VectorBlurOperation.cpp
source/blender/compositor/operations/COM_VectorBlurOperation.h
source/blender/compositor/operations/COM_VectorCurveOperation.cpp
source/blender/compositor/operations/COM_VectorCurveOperation.h
source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
source/blender/compositor/operations/COM_ViewerOperation.cpp
source/blender/compositor/operations/COM_ViewerOperation.h
source/blender/compositor/operations/COM_WriteBufferOperation.cpp
source/blender/compositor/operations/COM_WriteBufferOperation.h
source/blender/compositor/operations/COM_ZCombineOperation.cpp
source/blender/compositor/operations/COM_ZCombineOperation.h
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/anim_channels_edit.c
source/blender/editors/animation/anim_deps.c
source/blender/editors/animation/anim_draw.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/animation/anim_ipo_utils.c
source/blender/editors/animation/fmodifier_ui.c
source/blender/editors/animation/keyframes_draw.c
source/blender/editors/animation/keyframes_edit.c
source/blender/editors/animation/keyframing.c
source/blender/editors/animation/keyingsets.c
source/blender/editors/armature/armature_ops.c
source/blender/editors/armature/editarmature.c
source/blender/editors/armature/poseSlide.c
source/blender/editors/armature/poseUtils.c
source/blender/editors/armature/poselib.c
source/blender/editors/armature/poseobject.c
source/blender/editors/armature/reeb.c
source/blender/editors/curve/editfont.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_edit.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_armature.h
source/blender/editors/include/UI_interface.h
source/blender/editors/include/UI_view2d.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_anim.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/interface_panel.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_style.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/interface/resources.c
source/blender/editors/interface/view2d.c
source/blender/editors/interface/view2d_ops.c
source/blender/editors/io/io_collada.c
source/blender/editors/io/io_ops.c
source/blender/editors/mask/mask_edit.c
source/blender/editors/mask/mask_editaction.c
source/blender/editors/mask/mask_intern.h
source/blender/editors/mask/mask_ops.c
source/blender/editors/mask/mask_select.c
source/blender/editors/mesh/editface.c
source/blender/editors/mesh/editmesh_bvh.c
source/blender/editors/mesh/editmesh_select.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/meshtools.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_hook.c
source/blender/editors/object/object_modifier.c
source/blender/editors/object/object_transform.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/physics/physics_fluid.c
source/blender/editors/render/render_opengl.c
source/blender/editors/screen/area.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/screen/screen_intern.h
source/blender/editors/screen/screen_ops.c
source/blender/editors/sculpt_paint/paint_cursor.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_utils.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_buttons/buttons_header.c
source/blender/editors/space_clip/clip_ops.c
source/blender/editors/space_clip/space_clip.c
source/blender/editors/space_clip/tracking_select.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_file/fsmenu.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/space_graph/graph_select.c
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/image_draw.c
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_nla/nla_channels.c
source/blender/editors/space_node/CMakeLists.txt
source/blender/editors/space_node/SConscript
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_draw.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_node/space_node.c
source/blender/editors/space_text/text_ops.c
source/blender/editors/space_view3d/drawanimviz.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/drawvolume.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_fly.c
source/blender/editors/space_view3d/view3d_header.c
source/blender/editors/space_view3d/view3d_select.c
source/blender/editors/space_view3d/view3d_snap.c
source/blender/editors/space_view3d/view3d_view.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/uvedit/uvedit_ops.c
source/blender/editors/uvedit/uvedit_parametrizer.c
source/blender/editors/uvedit/uvedit_parametrizer.h
source/blender/editors/uvedit/uvedit_unwrap_ops.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_material.c
source/blender/ikplugin/intern/iksolver_plugin.c
source/blender/ikplugin/intern/itasc_plugin.cpp
source/blender/imbuf/IMB_moviecache.h
source/blender/imbuf/intern/IMB_anim.h
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/anim_movie.c
source/blender/imbuf/intern/imageprocess.c
source/blender/imbuf/intern/indexer.c
source/blender/imbuf/intern/indexer_dv.c
source/blender/imbuf/intern/jp2.c
source/blender/imbuf/intern/jpeg.c
source/blender/imbuf/intern/moviecache.c
source/blender/imbuf/intern/openexr/openexr_api.cpp
source/blender/imbuf/intern/openexr/openexr_multi.h
source/blender/imbuf/intern/openexr/openexr_stub.cpp
source/blender/imbuf/intern/png.c
source/blender/imbuf/intern/radiance_hdr.c
source/blender/imbuf/intern/tiff.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_meshdata_types.h
source/blender/makesdna/DNA_node_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_mesh_api.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_nodetree_types.h
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_userdef.c
source/blender/modifiers/intern/MOD_boolean_util.c
source/blender/modifiers/intern/MOD_collision.c
source/blender/modifiers/intern/MOD_fluidsim_util.c
source/blender/modifiers/intern/MOD_multires.c
source/blender/modifiers/intern/MOD_skin.c
source/blender/modifiers/intern/MOD_smoke.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_composite.h
source/blender/nodes/composite/node_composite_tree.c
source/blender/nodes/composite/node_composite_util.c
source/blender/nodes/composite/nodes/node_composite_keying.c
source/blender/nodes/composite/nodes/node_composite_trackpos.c [new file with mode: 0644]
source/blender/python/bmesh/bmesh_py_types.c
source/blender/python/bmesh/bmesh_py_types_meshdata.c
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_library.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/gpu.c
source/blender/python/mathutils/mathutils_Matrix.c
source/blender/quicktime/apple/quicktime_export.c
source/blender/render/extern/include/RE_pipeline.h
source/blender/render/intern/raytrace/rayobject_qbvh.cpp
source/blender/render/intern/raytrace/rayobject_svbvh.cpp
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/envmap.c
source/blender/render/intern/source/external_engine.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/occlusion.c
source/blender/render/intern/source/pipeline.c
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/render_result.c
source/blender/render/intern/source/render_texture.c
source/blender/render/intern/source/rendercore.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/shadeinput.c
source/blender/render/intern/source/shadeoutput.c
source/blender/render/intern/source/sunsky.c
source/blender/render/intern/source/texture_ocean.c
source/blender/render/intern/source/volume_precache.c
source/blender/render/intern/source/volumetric.c
source/blender/render/intern/source/voxeldata.c
source/blender/render/intern/source/zbuf.c
source/blender/windowmanager/intern/wm_cursors.c
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_gesture.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_keymap.c
source/blender/windowmanager/intern/wm_operators.c
source/blender/windowmanager/intern/wm_subwindow.c
source/creator/CMakeLists.txt
source/creator/creator.c
source/gameengine/Ketsji/BL_Texture.cpp
source/gameengine/Ketsji/KX_BulletPhysicsController.cpp
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
source/gameengine/Physics/Bullet/CcdPhysicsController.h
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.h

index d0a848ee6f77ff28f8cc19caac49ba92c110254e..31ae45b9bf0340bcad23ec5e0798d301052eb809 100644 (file)
@@ -1335,18 +1335,10 @@ Game Types (bge.types)
 
       Rigid body physics allows the object to roll on collisions.
 
-      .. note::
-         
-         This is not working with bullet physics yet.
-
    .. method:: disableRigidBody()
 
       Disables rigid body physics for this object.
 
-      .. note::
-
-         This is not working with bullet physics yet. The angular is removed but rigid body physics can still rotate it later.
-
    .. method:: setParent(parent, compound=True, ghost=True)
 
       Sets this object's parent.
@@ -4222,6 +4214,10 @@ Game Types (bge.types)
    .. attribute:: projection_matrix
 
       This camera's 4x4 projection matrix.
+         
+      .. note::
+      
+         This is the identity matrix prior to rendering the first frame (any Python done on frame 1). 
 
       :type: 4x4 Matrix [[float]]
 
@@ -4233,7 +4229,7 @@ Game Types (bge.types)
 
       .. note::
       
-         This matrix is regenerated every frame from the camera's position and orientation. 
+         This matrix is regenerated every frame from the camera's position and orientation. Also, this is the identity matrix prior to rendering the first frame (any Python done on frame 1).
 
    .. attribute:: camera_to_world
 
index a383ad317ab873f951e4cd8d69914bf6a78ac14f..bdcd3b6ba19fc0c81a42ef11a4b239bd7c21c66d 100644 (file)
@@ -378,10 +378,19 @@ void BVH::pack_instances(size_t nodes_size)
                int mesh_tri_offset = mesh->tri_offset;
 
                /* fill in node indexes for instances */
-               if(bvh->pack.is_leaf[0])
+               if(
+                  /* XXX, brecht. check this is needed!. it could be a bug elsewhere
+                   * /mango/pro/scenes/04_2e/04_2e.blend r2158. on Ian's system 192.168.3.27  - campbell */
+                  (bvh->pack.is_leaf.size() != 0) &&
+
+                  /* previously only checked this */
+                  bvh->pack.is_leaf[0])
+               {
                        pack.object_node[object_offset++] = -noffset-1;
-               else
+               }
+               else {
                        pack.object_node[object_offset++] = noffset;
+               }
 
                mesh_map[mesh] = pack.object_node[object_offset-1];
 
index 44d784ba74135ba4c2c0617bb5d91cb1e021876d..2924ed30b8816e6424f0af7c7f14fcfe0ab8aee6 100644 (file)
@@ -26,8 +26,6 @@
 #include "util_path.h"
 #include "util_types.h"
 
-#define BOOST_FILESYSTEM_VERSION 2
-
 #include <boost/filesystem.hpp> 
 #include <boost/algorithm/string.hpp>
 
@@ -117,7 +115,7 @@ void Cache::clear_except(const string& name, const set<string>& except)
                boost::filesystem::directory_iterator it(dir), it_end;
 
                for(; it != it_end; it++) {
-                       string filename = it->path().filename();
+                       string filename = it->path().filename().string();
 
                        if(boost::starts_with(filename, name))
                                if(except.find(filename) == except.end())
index 717aa34c4265769bacce5137bcb8dd808fa14edb..53dbfe9a42c8b1d205bba7e5417b9eb836e0e52f 100644 (file)
@@ -26,8 +26,6 @@ OIIO_NAMESPACE_USING
 
 #include <stdio.h>
 
-#define BOOST_FILESYSTEM_VERSION 2
-
 #include <boost/filesystem.hpp> 
 #include <boost/algorithm/string.hpp>
 
@@ -60,7 +58,7 @@ string path_user_get(const string& sub)
 
 string path_filename(const string& path)
 {
-       return boost::filesystem::path(path).filename();
+       return boost::filesystem::path(path).filename().string();
 }
 
 string path_dirname(const string& path)
index 2d8f5e7890ca5d90ad46262fc40974d5dd66fc6b..03a952fafb3af41f31426a0c088c1dcb8c4379cc 100644 (file)
@@ -93,9 +93,12 @@ GHOST_SystemX11(
                abort(); //was return before, but this would just mean it will crash later
        }
 
-       /* Open a connection to the X input manager */
 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
-       m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
+       /* note -- don't open connection to XIM server here, because the locale
+        * has to be set before opening the connection but setlocale() has not
+        * been called yet.  the connection will be opened after entering
+        * the event loop. */
+       m_xim = NULL;
 #endif
 
        m_delete_window_atom 
@@ -273,6 +276,35 @@ createWindow(
        return window;
 }
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+static void destroyIMCallback(XIM xim, XPointer ptr, XPointer data)
+{
+       GHOST_PRINT("XIM server died\n");
+
+       if (ptr)
+               *(XIM *)ptr = NULL;
+}
+
+bool GHOST_SystemX11::openX11_IM()
+{
+       if (!m_display)
+               return false;
+
+       /* set locale modifiers such as "@im=ibus" specified by XMODIFIERS */
+       XSetLocaleModifiers("");
+
+       m_xim = XOpenIM(m_display, NULL, (char *)GHOST_X11_RES_NAME, (char *)GHOST_X11_RES_CLASS);
+       if (!m_xim)
+               return false;
+
+       XIMCallback destroy;
+       destroy.callback = (XIMProc)destroyIMCallback;
+       destroy.client_data = (XPointer)&m_xim;
+       XSetIMValues(m_xim, XNDestroyCallback, &destroy, NULL);
+       return true;
+}
+#endif
+
 GHOST_WindowX11 *
 GHOST_SystemX11::
 findGhostWindow(
@@ -408,6 +440,38 @@ processEvents(
                while (XPending(m_display)) {
                        XEvent xevent;
                        XNextEvent(m_display, &xevent);
+
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+                       /* open connection to XIM server and create input context (XIC)
+                        * when receiving the first FocusIn or KeyPress event after startup,
+                        * or recover XIM and XIC when the XIM server has been restarted */
+                       if (xevent.type == FocusIn || xevent.type == KeyPress) {
+                               if (!m_xim && openX11_IM()) {
+                                       GHOST_PRINT("Connected to XIM server\n");
+                               }
+
+                               if (m_xim) {
+                                       GHOST_WindowX11 * window = findGhostWindow(xevent.xany.window);
+                                       if (window && !window->getX11_XIC() && window->createX11_XIC()) {
+                                               GHOST_PRINT("XIM input context created\n");
+                                               if (xevent.type == KeyPress)
+                                                       /* we can assume the window has input focus
+                                                        * here, because key events are received only
+                                                        * when the window is focused. */
+                                                       XSetICFocus(window->getX11_XIC());
+                                       }
+                               }
+                       }
+
+                       /* dispatch event to XIM server */
+                       if ((XFilterEvent(&xevent, (Window)NULL) == True) && (xevent.type != KeyRelease)) {
+                               /* do nothing now, the event is consumed by XIM.
+                                * however, KeyRelease event should be processed
+                                * here, otherwise modifiers remain activated.   */
+                               continue;
+                       }
+#endif
+
                        processEvent(&xevent);
                        anyProcessed = true;
                }
@@ -535,7 +599,19 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                        XKeyEvent *xke = &(xe->xkey);
                        KeySym key_sym = XLookupKeysym(xke, 0);
                        char ascii;
-                       char utf8_buf[6]; /* 6 is enough for a utf8 char */
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+                       /* utf8_array[] is initial buffer used for Xutf8LookupString().
+                        * if the length of the utf8 string exceeds this array, allocate
+                        * another memory area and call Xutf8LookupString() again.
+                        * the last 5 bytes are used to avoid segfault that might happen
+                        * at the end of this buffer when the constructor of GHOST_EventKey
+                        * reads 6 bytes regardless of the effective data length. */
+                       char utf8_array[16 * 6 + 5]; /* 16 utf8 characters */
+                       char *utf8_buf = utf8_array;
+                       int len = 1; /* at least one null character will be stored */
+#else
+                       char *utf8_buf = NULL;
+#endif
                        
                        GHOST_TKey gkey = convertXKey(key_sym);
                        GHOST_TEventType type = (xke->type == KeyPress) ? 
@@ -547,15 +623,20 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                        
 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
                        /* getting unicode on key-up events gives XLookupNone status */
-                       if (xke->type == KeyPress) {
+                       XIC xic = window->getX11_XIC();
+                       if (xic && xke->type == KeyPress) {
                                Status status;
-                               int len;
 
                                /* use utf8 because its not locale depentant, from xorg docs */
-                               if (!(len = Xutf8LookupString(window->getX11_XIC(), xke, utf8_buf, sizeof(utf8_buf), &key_sym, &status))) {
+                               if (!(len = Xutf8LookupString(xic, xke, utf8_buf, sizeof(utf8_array) - 5, &key_sym, &status))) {
                                        utf8_buf[0] = '\0';
                                }
 
+                               if (status == XBufferOverflow) {
+                                       utf8_buf = (char *) malloc(len + 5);
+                                       len = Xutf8LookupString(xic, xke, utf8_buf, len, &key_sym, &status);
+                               }
+
                                if ((status == XLookupChars || status == XLookupBoth)) {
                                        if ((unsigned char)utf8_buf[0] >= 32) { /* not an ascii control character */
                                                /* do nothing for now, this is valid utf8 */
@@ -571,19 +652,16 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                                else {
                                        printf("Bad keycode lookup. Keysym 0x%x Status: %s\n",
                                               (unsigned int) key_sym,
-                                              (status == XBufferOverflow ? "BufferOverflow" :
-                                               status == XLookupNone ? "XLookupNone" :
+                                              (status == XLookupNone ? "XLookupNone" :
                                                status == XLookupKeySym ? "XLookupKeySym" :
                                                "Unknown status"));
 
-                                       printf("'%.*s' %p %p\n", len, utf8_buf, window->getX11_XIC(), m_xim);
+                                       printf("'%.*s' %p %p\n", len, utf8_buf, xic, m_xim);
                                }
                        }
                        else {
                                utf8_buf[0] = '\0';
                        }
-#else
-                       utf8_buf[0] = '\0';
 #endif
 
                        g_event = new
@@ -595,6 +673,42 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                            ascii,
                            utf8_buf
                            );
+
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+                       /* when using IM for some languages such as Japanese,
+                        * one event inserts multiple utf8 characters */
+                       if (xic && xke->type == KeyPress) {
+                               unsigned char c;
+                               int i = 0;
+                               while (1) {
+                                       /* search character boundary */
+                                       if ((unsigned char)utf8_buf[i++] > 0x7f) {
+                                               for (; i < len; ++i) {
+                                                       c = utf8_buf[i];
+                                                       if (c < 0x80 || c > 0xbf) break;
+                                               }
+                                       }
+
+                                       if (i >= len) break;
+
+                                       /* enqueue previous character */
+                                       pushEvent(g_event);
+
+                                       g_event = new
+                                                 GHOST_EventKey(
+                                           getMilliSeconds(),
+                                           type,
+                                           window,
+                                           gkey,
+                                           '\0',
+                                           &utf8_buf[i]
+                                           );
+                               }
+                       }
+
+                       if (utf8_buf != utf8_array)
+                               free(utf8_buf);
+#endif
                        
                        break;
                }
@@ -675,6 +789,16 @@ GHOST_SystemX11::processEvent(XEvent *xe)
                        GHOST_TEventType gtype = (xfe.type == FocusIn) ? 
                                                 GHOST_kEventWindowActivate : GHOST_kEventWindowDeactivate;
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+                       XIC xic = window->getX11_XIC();
+                       if (xic) {
+                               if (xe->type == FocusIn)
+                                       XSetICFocus(xic);
+                               else
+                                       XUnsetICFocus(xic);
+                       }
+#endif
+
                        g_event = new 
                                  GHOST_Event(
                            getMilliSeconds(),
index fd5a33c02d749637db37f38d496a09bf45cd38c5..d86790e262f2d5e0c966d5d7354fa38d62bbca9e 100644 (file)
@@ -309,6 +309,10 @@ private:
         * X11 window xwind
         */
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+       bool openX11_IM();
+#endif
+
        GHOST_WindowX11 *
        findGhostWindow(
            Window xwind
index f94f08b1d1397420acafb0f224758369b7b15816..ac6cc548f329f1b67454d3776b40f6bf78585563 100644 (file)
@@ -1235,9 +1235,11 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
         
         // Progress fill
         progressBox = NSInsetRect(progressBox, 1, 1);
-        [[NSColor knobColor] setFill];
+        
         progressBox.size.width = progressBox.size.width * progress;
-               NSRectFill(progressBox);
+        NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] endingColor:[NSColor lightGrayColor]];
+        [gradient drawInRect:progressBox angle:90];
+        [gradient release];
                
                [dockIcon unlockFocus];
                
index cdb274b0e611ccb395dbddc5b28bd4c030e8910f..80d5b5a4652935f737ccf1dc9aad0bc16bffa8ec 100644 (file)
@@ -401,10 +401,7 @@ GHOST_WindowX11(
        }
 
 #if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
-       m_xic = XCreateIC(m_system->getX11_XIM(), XNClientWindow, m_window, XNFocusWindow, m_window,
-                         XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
-                         XNResourceName, GHOST_X11_RES_NAME, XNResourceClass,
-                         GHOST_X11_RES_CLASS, NULL);
+       m_xic = NULL;
 #endif
 
        // Set the window icon
@@ -419,8 +416,8 @@ GHOST_WindowX11(
        x_image = XCreateImage(display, m_visual->visual, 24, ZPixmap, 0, NULL, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 32, 0);
        mask_image = XCreateImage(display, m_visual->visual, 1, ZPixmap, 0, NULL,  BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 8, 0);
        
-       x_image->data = (char *)malloc(x_image->bytes_per_line * BLENDER_ICON_HEIGHT);
-       mask_image->data = (char *)malloc(mask_image->bytes_per_line * BLENDER_ICON_HEIGHT);
+       x_image->data = (char *)calloc(x_image->bytes_per_line * BLENDER_ICON_HEIGHT, 1);
+       mask_image->data = (char *)calloc(mask_image->bytes_per_line * BLENDER_ICON_HEIGHT, 1);
        
        /* copy the BLENDER_ICON_48x48x24 into the XImage */
        unsigned char *col = BLENDER_ICON_48x48x24;
@@ -429,7 +426,11 @@ GHOST_WindowX11(
                for (py = 0; py < BLENDER_ICON_HEIGHT; py++, col += 3) {
                        /* mask out pink */
                        if (col[0] == 255 && col[1] == 0 && col[2] == 255) {
+#if 0
+                               /* instead, use calloc above */
+                               XPutPixel(x_image, px, py, 0); /* avoid uninitialized memory, otherwise not needed */
                                XPutPixel(mask_image, px, py, 0);
+#endif
                        }
                        else {
                                XPutPixel(x_image, px, py, (col[0] << 16) + (col[1] << 8) + col[2]);
@@ -474,6 +475,47 @@ GHOST_WindowX11(
        XFlush(m_display);
 }
 
+#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
+static void destroyICCallback(XIC xic, XPointer ptr, XPointer data)
+{
+       GHOST_PRINT("XIM input context destroyed\n");
+
+       if (ptr) {
+               *(XIC *)ptr = NULL;
+       }
+}
+
+bool GHOST_WindowX11::createX11_XIC()
+{
+       XIM xim = m_system->getX11_XIM();
+       if (!xim)
+               return false;
+
+       XICCallback destroy;
+       destroy.callback = (XICProc)destroyICCallback;
+       destroy.client_data = (XPointer)&m_xic;
+       m_xic = XCreateIC(xim, XNClientWindow, m_window, XNFocusWindow, m_window,
+                         XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
+                         XNResourceName, GHOST_X11_RES_NAME,
+                         XNResourceClass, GHOST_X11_RES_CLASS,
+                         XNDestroyCallback, &destroy,
+                         NULL);
+       if (!m_xic)
+               return false;
+
+       unsigned long fevent;
+       XGetICValues(m_xic, XNFilterEvents, &fevent, NULL);
+       XSelectInput(m_display, m_window,
+                    ExposureMask | StructureNotifyMask |
+                    KeyPressMask | KeyReleaseMask |
+                    EnterWindowMask | LeaveWindowMask |
+                    ButtonPressMask | ButtonReleaseMask |
+                    PointerMotionMask | FocusChangeMask |
+                    PropertyChangeMask | fevent);
+       return true;
+}
+#endif
+
 #ifdef WITH_X11_XINPUT
 /* 
  * Dummy function to get around IO Handler exiting if device invalid
@@ -1143,7 +1185,6 @@ GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
 }
 
 #include <iostream>
-using namespace std;
 
 GHOST_TSuccess
 GHOST_WindowX11::
index a04a43bc33a49190cca868d57b1a604209bb036c..753d8960a18cb4860f8169011b6517edd9a45fe8 100644 (file)
@@ -234,6 +234,8 @@ public:
        XIC getX11_XIC() {
                return m_xic;
        }
+
+       bool createX11_XIC();
 #endif
 
 #ifdef WITH_XDND
index 4bb8cba6810ac9196fabaa003334aa08505921b0..7fcfba5afec4687ebc39b8ee69ab2aa97a513a61 100644 (file)
 #include <stdio.h> /* needed for FILE* */
 #include "MEM_sys_types.h" /* needed for uintptr_t */
 
-#ifndef WARN_UNUSED
-#  ifdef __GNUC__
-#    define WARN_UNUSED  __attribute__((warn_unused_result))
-#  else
-#    define WARN_UNUSED
-#  endif
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -78,14 +70,17 @@ extern "C" {
        /** Returns the length of the allocated memory segment pointed at
         * by vmemh. If the pointer was not previously allocated by this
         * module, the result is undefined.*/
-       size_t MEM_allocN_len(void *vmemh) WARN_UNUSED;
+       size_t MEM_allocN_len(void *vmemh)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+#endif
+       ;
 
        /**
         * Release memory previously allocatred by this module. 
         */
        short MEM_freeN(void *vmemh);
 
-
        /**
         * Return zero if memory is not in allocated list
         */
@@ -94,30 +89,57 @@ extern "C" {
        /**
         * Duplicates a block of memory, and returns a pointer to the
         * newly allocated block.  */
-       void *MEM_dupallocN(void *vmemh) WARN_UNUSED;
+       void *MEM_dupallocN(void *vmemh)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+#endif
+       ;
 
        /**
         * Reallocates a block of memory, and returns pointer to the newly
         * allocated block, the old one is freed. this is not as optimized
         * as a system realloc but just makes a new allocation and copies
         * over from existing memory. */
-       void *MEM_reallocN(void *vmemh, size_t len) WARN_UNUSED;
+       void *MEM_reallocN(void *vmemh, size_t len)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+       __attribute__((alloc_size(2)))
+#endif
+       ;
 
        /**
         * Allocate a block of memory of size len, with tag name str. The
         * memory is cleared. The name must be static, because only a
         * pointer to it is stored ! */
-       void *MEM_callocN(size_t len, const char * str) WARN_UNUSED;
+       void *MEM_callocN(size_t len, const char * str)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+       __attribute__((nonnull))
+       __attribute__((alloc_size(1)))
+#endif
+       ;
        
        /** Allocate a block of memory of size len, with tag name str. The
         * name must be a static, because only a pointer to it is stored !
         * */
-       void *MEM_mallocN(size_t len, const char * str) WARN_UNUSED;
+       void *MEM_mallocN(size_t len, const char * str)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+       __attribute__((nonnull))
+       __attribute__((alloc_size(1)))
+#endif
+       ;
        
        /** Same as callocN, clears memory and uses mmap (disk cached) if supported.
         * Can be free'd with MEM_freeN as usual.
         * */
-       void *MEM_mapallocN(size_t len, const char * str) WARN_UNUSED;
+       void *MEM_mapallocN(size_t len, const char * str)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+       __attribute__((nonnull))
+       __attribute__((alloc_size(1)))
+#endif
+       ;
 
        /** Print a list of the names and sizes of all allocated memory
         * blocks. as a python dict for easy investigation */ 
@@ -162,7 +184,11 @@ extern "C" {
        void MEM_reset_peak_memory(void);
 
        /** Get the peak memory usage in bytes, including mmap allocations. */
-       uintptr_t MEM_get_peak_memory(void) WARN_UNUSED;
+       uintptr_t MEM_get_peak_memory(void)
+#ifdef __GNUC__
+       __attribute__((warn_unused_result))
+#endif
+       ;
 
 #ifndef NDEBUG
 const char *MEM_name_ptr(void *vmemh);
index c00e94666747e75abb1d0167fb4c1a0ca02df435..9ba8c0f3d58e8ca199eb5d2d5eb9d459fafd883b 100644 (file)
@@ -163,6 +163,9 @@ static int malloc_debug_memset = 0;
 /* implementation                                                        */
 /* --------------------------------------------------------------------- */
 
+#ifdef __GNUC__
+__attribute__ ((format(printf, 1, 2)))
+#endif
 static void print_error(const char *str, ...)
 {
        char buf[512];
@@ -325,7 +328,7 @@ void *MEM_mallocN(size_t len, const char *str)
        }
        mem_unlock_thread();
        print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
-                   SIZET_ARG(len), str, mem_in_use);
+                   SIZET_ARG(len), str, (unsigned int) mem_in_use);
        return NULL;
 }
 
@@ -351,7 +354,7 @@ void *MEM_callocN(size_t len, const char *str)
        }
        mem_unlock_thread();
        print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n",
-                   SIZET_ARG(len), str, mem_in_use);
+                   SIZET_ARG(len), str, (unsigned int) mem_in_use);
        return NULL;
 }
 
@@ -384,7 +387,7 @@ void *MEM_mapallocN(size_t len, const char *str)
                mem_unlock_thread();
                print_error("Mapalloc returns null, fallback to regular malloc: "
                            "len=" SIZET_FORMAT " in %s, total %u\n",
-                           SIZET_ARG(len), str, mmap_in_use);
+                           SIZET_ARG(len), str, (unsigned int) mmap_in_use);
                return MEM_callocN(len, str);
        }
 }
index 9a36b67aa2f8c11ae1f9bd197edec89f295da6bf..801ee154d401c9395264a26c71f2a0cfe0193103 100644 (file)
@@ -32,7 +32,7 @@
  * @section MEM_CacheLimiter
  * This class defines a generic memory cache management system
  * to limit memory usage to a fixed global maximum.
- * 
+ *
  * Please use the C-API in MEM_CacheLimiterC-Api.h for code written in C.
  *
  * Usage example:
  * public:
  *       ~BigFatImage() { tell_everyone_we_are_gone(this); }
  * };
- * 
+ *
  * void doit() {
  *     MEM_Cache<BigFatImage> BigFatImages;
  *
  *     MEM_Cache_Handle<BigFatImage>* h = BigFatImages.insert(new BigFatImage);
- * 
+ *
  *     BigFatImages.enforce_limits();
  *     h->ref();
  *
@@ -58,6 +58,8 @@
  */
 
 #include <list>
+#include <queue>
+#include <vector>
 #include "MEM_Allocator.h"
 
 template<class T>
@@ -65,36 +67,44 @@ class MEM_CacheLimiter;
 
 #ifndef __MEM_CACHELIMITERC_API_H__
 extern "C" {
-       extern void MEM_CacheLimiter_set_maximum(size_t m);
-       extern size_t MEM_CacheLimiter_get_maximum();
+       void MEM_CacheLimiter_set_maximum(size_t m);
+       size_t MEM_CacheLimiter_get_maximum();
 };
 #endif
 
 template<class T>
 class MEM_CacheLimiterHandle {
 public:
-       explicit MEM_CacheLimiterHandle(T * data_, 
-                                        MEM_CacheLimiter<T> * parent_) 
-               : data(data_), refcount(0), parent(parent_) { }
+       explicit MEM_CacheLimiterHandle(T * data_,MEM_CacheLimiter<T> *parent_) :
+               data(data_),
+               refcount(0),
+               parent(parent_)
+       { }
 
-       void ref() { 
-               refcount++; 
+       void ref() {
+               refcount++;
        }
-       void unref() { 
-               refcount--; 
+
+       void unref() {
+               refcount--;
        }
-       T * get() { 
-               return data; 
+
+       T *get() {
+               return data;
        }
-       const T * get() const { 
-               return data; 
+
+       const T *get() const {
+               return data;
        }
-       int get_refcount() const { 
-               return refcount; 
+
+       int get_refcount() const {
+               return refcount;
        }
-       bool can_destroy() const { 
-               return !data || !refcount; 
+
+       bool can_destroy() const {
+               return !data || !refcount;
        }
+
        bool destroy_if_possible() {
                if (can_destroy()) {
                        delete data;
@@ -104,48 +114,64 @@ public:
                }
                return false;
        }
+
        void unmanage() {
                parent->unmanage(this);
        }
+
        void touch() {
                parent->touch(this);
        }
+
+       void set_priority(int priority) {
+               this->priority = priority;
+       }
+
+       int get_priority(void) {
+               return this->priority;
+       }
+
 private:
        friend class MEM_CacheLimiter<T>;
 
        T * data;
        int refcount;
-       typename std::list<MEM_CacheLimiterHandle<T> *,
-         MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator me;
+       int priority;
+       typename std::list<MEM_CacheLimiterHandle<T> *, MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator me;
        MEM_CacheLimiter<T> * parent;
 };
 
 template<class T>
 class MEM_CacheLimiter {
 public:
-       typedef typename std::list<MEM_CacheLimiterHandle<T> *,
-         MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator iterator;
        typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
+       typedef int    (*MEM_CacheLimiter_ItemPriority_Func) (void *item, int default_priority);
+
        MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func getDataSize_)
                : getDataSize(getDataSize_) {
        }
+
        ~MEM_CacheLimiter() {
                for (iterator it = queue.begin(); it != queue.end(); it++) {
                        delete *it;
                }
        }
-       MEM_CacheLimiterHandle<T> * insert(T * elem) {
+
+       MEM_CacheLimiterHandle<T> *insert(T * elem) {
                queue.push_back(new MEM_CacheLimiterHandle<T>(elem, this));
                iterator it = queue.end();
                --it;
                queue.back()->me = it;
                return queue.back();
        }
-       void unmanage(MEM_CacheLimiterHandle<T> * handle) {
+
+       void unmanage(MEM_CacheLimiterHandle<T> *handle) {
                queue.erase(handle->me);
                delete handle;
        }
+
        void enforce_limits() {
+               MEM_CachePriorityQueue priority_queue;
                size_t max = MEM_CacheLimiter_get_maximum();
                size_t mem_in_use, cur_size;
 
@@ -159,27 +185,33 @@ public:
                        mem_in_use = MEM_get_memory_in_use();
                }
 
-               for (iterator it = queue.begin(); 
-                    it != queue.end() && mem_in_use > max;)
-               {
-                       iterator jt = it;
-                       ++it;
+               if (mem_in_use <= max) {
+                       return;
+               }
 
-                       if(getDataSize) {
-                               cur_size= getDataSize((*jt)->get()->get_data());
-                       } else {
-                               cur_size= mem_in_use;
-                       }
+               priority_queue = get_priority_queue();
+
+               while (!priority_queue.empty() && mem_in_use > max) {
+                       MEM_CacheElementPtr elem = priority_queue.top();
 
-                       (*jt)->destroy_if_possible();
+                       priority_queue.pop();
 
                        if(getDataSize) {
-                               mem_in_use-= cur_size;
+                               cur_size = getDataSize(elem->get()->get_data());
                        } else {
-                               mem_in_use-= cur_size - MEM_get_memory_in_use();
+                               cur_size = mem_in_use;
+                       }
+
+                       if (elem->destroy_if_possible()) {
+                               if (getDataSize) {
+                                       mem_in_use -= cur_size;
+                               } else {
+                                       mem_in_use -= cur_size - MEM_get_memory_in_use();
+                               }
                        }
                }
        }
+
        void touch(MEM_CacheLimiterHandle<T> * handle) {
                queue.push_back(handle);
                queue.erase(handle->me);
@@ -187,7 +219,24 @@ public:
                --it;
                handle->me = it;
        }
+
+       void set_item_priority_func(MEM_CacheLimiter_ItemPriority_Func item_priority_func) {
+               getItemPriority = item_priority_func;
+       }
+
 private:
+       typedef MEM_CacheLimiterHandle<T> *MEM_CacheElementPtr;
+       typedef std::list<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
+       typedef typename MEM_CacheQueue::iterator iterator;
+
+       struct compare_element_priority : public std::binary_function<MEM_CacheElementPtr, MEM_CacheElementPtr, bool> {
+               bool operator()(const MEM_CacheElementPtr left_elem, const MEM_CacheElementPtr right_elem) const {
+                       return left_elem->get_priority() > right_elem->get_priority();
+               }
+       };
+
+       typedef std::priority_queue<MEM_CacheElementPtr, std::vector<MEM_CacheElementPtr>, compare_element_priority > MEM_CachePriorityQueue;
+
        size_t total_size() {
                size_t size = 0;
                for (iterator it = queue.begin(); it != queue.end(); it++) {
@@ -196,9 +245,33 @@ private:
                return size;
        }
 
-       std::list<MEM_CacheLimiterHandle<T>*,
-         MEM_Allocator<MEM_CacheLimiterHandle<T> *> > queue;
+       MEM_CachePriorityQueue get_priority_queue(void) {
+               MEM_CachePriorityQueue priority_queue;
+               iterator it;
+               int i;
+
+               for (it = queue.begin(), i = 0; it != queue.end(); it++, i++) {
+                       MEM_CacheElementPtr elem = *it;
+                       int priority;
+
+                       /* by default 0 means higherst priority element */
+                       priority = -(queue.size() - i - 1);
+
+                       if (getItemPriority) {
+                               priority = getItemPriority(elem->get()->get_data(), priority);
+                       }
+
+                       elem->set_priority(priority);
+
+                       priority_queue.push(elem);
+               }
+
+               return priority_queue;
+       }
+
+       MEM_CacheQueue queue;
        MEM_CacheLimiter_DataSize_Func getDataSize;
+       MEM_CacheLimiter_ItemPriority_Func getItemPriority;
 };
 
 #endif // __MEM_CACHELIMITER_H__
index 4ed692fb55f503c3a428c164a2ac7996b06f60a6..1ae5e9df1c6e65a377a4be95345343c2f8d01927 100644 (file)
@@ -31,7 +31,7 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-       
+
 struct MEM_CacheLimiter_s;
 struct MEM_CacheLimiterHandle_s;
 
@@ -39,106 +39,111 @@ typedef struct MEM_CacheLimiter_s MEM_CacheLimiterC;
 typedef struct MEM_CacheLimiterHandle_s MEM_CacheLimiterHandleC;
 
 /* function used to remove data from memory */
-typedef void(*MEM_CacheLimiter_Destruct_Func)(void*);
+typedef void (*MEM_CacheLimiter_Destruct_Func)(void*);
 
 /* function used to measure stored data element size */
-typedef size_t(*MEM_CacheLimiter_DataSize_Func) (void*);
+typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void*);
+
+/* function used to measure priority of item when freeing memory */
+typedef int (*MEM_CacheLimiter_ItemPriority_Func) (void*, int);
 
 #ifndef __MEM_CACHELIMITER_H__
-extern void MEM_CacheLimiter_set_maximum(size_t m);
-extern int MEM_CacheLimiter_get_maximum(void);
+void MEM_CacheLimiter_set_maximum(size_t m);
+int MEM_CacheLimiter_get_maximum(void);
 #endif /* __MEM_CACHELIMITER_H__ */
-/** 
- * Create new MEM_CacheLimiter object 
+
+/**
+ * Create new MEM_CacheLimiter object
  * managed objects are destructed with the data_destructor
  *
  * @param data_destructor
  * @return A new MEM_CacheLimter object
  */
 
-extern MEM_CacheLimiterC * new_MEM_CacheLimiter(
-       MEM_CacheLimiter_Destruct_Func data_destructor,
-       MEM_CacheLimiter_DataSize_Func data_size);
+MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_destructor,
+                                         MEM_CacheLimiter_DataSize_Func data_size);
 
-/** 
+/**
  * Delete MEM_CacheLimiter
- * 
+ *
  * Frees the memory of the CacheLimiter but does not touch managed objects!
  *
  * @param This "This" pointer
  */
 
-extern void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This);
+void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This);
 
-/** 
+/**
  * Manage object
- * 
+ *
  * @param This "This" pointer, data data object to manage
  * @return CacheLimiterHandle to ref, unref, touch the managed object
  */
-       
-extern MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert(
-       MEM_CacheLimiterC * This, void * data);
 
-/** 
+MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC * This, void * data);
+
+/**
  * Free objects until memory constraints are satisfied
- * 
+ *
  * @param This "This" pointer
  */
 
-extern void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This);
+void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This);
 
-/** 
- * Unmanage object previously inserted object. 
+/**
+ * Unmanage object previously inserted object.
  * Does _not_ delete managed object!
- * 
+ *
  * @param This "This" pointer, handle of object
  */
-       
-extern void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle);
 
+void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle);
 
-/** 
+
+/**
  * Raise priority of object (put it at the tail of the deletion chain)
- * 
+ *
  * @param handle of object
  */
-       
-extern void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle);
 
-/** 
+void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC *handle);
+
+/**
  * Increment reference counter. Objects with reference counter != 0 are _not_
  * deleted.
- * 
+ *
  * @param handle of object
  */
-       
-extern void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle);
 
-/** 
+void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC *handle);
+
+/**
  * Decrement reference counter. Objects with reference counter != 0 are _not_
  * deleted.
- * 
+ *
  * @param handle of object
  */
-       
-extern void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle);
 
-/** 
+void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC *handle);
+
+/**
  * Get reference counter.
- * 
+ *
  * @param This "This" pointer, handle of object
  */
-       
-extern int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle);
 
-/** 
+int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle);
+
+/**
  * Get pointer to managed object
- * 
+ *
  * @param handle of object
  */
-       
-extern void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle);
+
+void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle);
+
+void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
+                                            MEM_CacheLimiter_ItemPriority_Func item_priority_func);
 
 #ifdef __cplusplus
 }
index cfa6a207e1cf6613172fd8ac7caeaab4c635d4f9..81a1ce670aeecbbaa1842d983ef728ac2b91a8b7 100644 (file)
@@ -31,7 +31,7 @@
 
 static size_t & get_max()
 {
-       static size_t m = 32*1024*1024;
+       static size_t m = 32 * 1024 * 1024;
        return m;
 }
 
@@ -50,8 +50,7 @@ class MEM_CacheLimiterCClass;
 
 typedef MEM_CacheLimiterHandle<MEM_CacheLimiterHandleCClass> handle_t;
 typedef MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache_t;
-typedef std::list<MEM_CacheLimiterHandleCClass*,
-                 MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t;
+typedef std::list<MEM_CacheLimiterHandleCClass*, MEM_Allocator<MEM_CacheLimiterHandleCClass* > > list_t;
 
 class MEM_CacheLimiterCClass {
 public:
@@ -59,11 +58,10 @@ public:
                : data_destructor(data_destructor_), cache(data_size) {
        }
        ~MEM_CacheLimiterCClass();
-       
+
        handle_t * insert(void * data);
 
-       void destruct(void * data,
-                     list_t::iterator it);
+       void destruct(void * data, list_t::iterator it);
 
        cache_t * get_cache() {
                return &cache;
@@ -72,42 +70,48 @@ private:
        MEM_CacheLimiter_Destruct_Func data_destructor;
 
        MEM_CacheLimiter<MEM_CacheLimiterHandleCClass> cache;
-       
+
        list_t cclass_list;
 };
 
 class MEM_CacheLimiterHandleCClass {
 public:
-       MEM_CacheLimiterHandleCClass(void * data_,
-                                    MEM_CacheLimiterCClass * parent_)
-           : data(data_), parent(parent_) { }
+       MEM_CacheLimiterHandleCClass(void * data_, MEM_CacheLimiterCClass * parent_) :
+               data(data_),
+               parent(parent_)
+       { }
+
        ~MEM_CacheLimiterHandleCClass();
+
        void set_iter(list_t::iterator it_) {
                it = it_;
        }
+
        void set_data(void * data_) {
                data = data_;
        }
-       void * get_data() const {
+
+       void *get_data() const {
                return data;
        }
+
 private:
-       void * data;
-       MEM_CacheLimiterCClass * parent;
+       void *data;
+       MEM_CacheLimiterCClass *parent;
        list_t::iterator it;
 };
 
-handle_t * MEM_CacheLimiterCClass::insert(void * data) 
+handle_t *MEM_CacheLimiterCClass::insert(void * data)
 {
        cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
        list_t::iterator it = cclass_list.end();
        --it;
        cclass_list.back()->set_iter(it);
-       
+
        return cache.insert(cclass_list.back());
 }
 
-void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it) 
+void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it)
 {
        data_destructor(data);
        cclass_list.erase(it);
@@ -123,77 +127,78 @@ MEM_CacheLimiterHandleCClass::~MEM_CacheLimiterHandleCClass()
 MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
 {
        // should not happen, but don't leak memory in this case...
-       for (list_t::iterator it = cclass_list.begin();
-            it != cclass_list.end(); it++) {
+       for (list_t::iterator it = cclass_list.begin(); it != cclass_list.end(); it++) {
                (*it)->set_data(0);
+
                delete *it;
        }
 }
 
 // ----------------------------------------------------------------------
 
-static inline MEM_CacheLimiterCClass* cast(MEM_CacheLimiterC * l)
+static inline MEM_CacheLimiterCClass *cast(MEM_CacheLimiterC *l)
 {
-       return (MEM_CacheLimiterCClass*) l;
+       return (MEM_CacheLimiterCClass *) l;
 }
 
-static inline handle_t* cast(MEM_CacheLimiterHandleC * l)
+static inline handle_t *cast(MEM_CacheLimiterHandleC *l)
 {
-       return (handle_t*) l;
+       return (handle_t *) l;
 }
 
-MEM_CacheLimiterC * new_MEM_CacheLimiter(
-       MEM_CacheLimiter_Destruct_Func data_destructor,
-       MEM_CacheLimiter_DataSize_Func data_size)
+MEM_CacheLimiterC *new_MEM_CacheLimiter(MEM_CacheLimiter_Destruct_Func data_destructor,
+                                        MEM_CacheLimiter_DataSize_Func data_size)
 {
-       return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass(
-               data_destructor,
-               data_size);
+       return (MEM_CacheLimiterC *) new MEM_CacheLimiterCClass(data_destructor, data_size);
 }
 
-void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This)
+void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This)
 {
        delete cast(This);
 }
 
-MEM_CacheLimiterHandleC * MEM_CacheLimiter_insert(
-       MEM_CacheLimiterC * This, void * data)
+MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC *This, void *data)
 {
        return (MEM_CacheLimiterHandleC *) cast(This)->insert(data);
 }
 
-void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC * This)
+void MEM_CacheLimiter_enforce_limits(MEM_CacheLimiterC *This)
 {
        cast(This)->get_cache()->enforce_limits();
 }
-       
-void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC * handle)
+
+void MEM_CacheLimiter_unmanage(MEM_CacheLimiterHandleC *handle)
 {
        cast(handle)->unmanage();
 }
-       
-void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC * handle)
+
+void MEM_CacheLimiter_touch(MEM_CacheLimiterHandleC *handle)
 {
        cast(handle)->touch();
 }
-       
-void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC * handle)
+
+void MEM_CacheLimiter_ref(MEM_CacheLimiterHandleC *handle)
 {
        cast(handle)->ref();
 }
-       
-void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC * handle)
+
+void MEM_CacheLimiter_unref(MEM_CacheLimiterHandleC *handle)
 {
        cast(handle)->unref();
 }
 
-int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC * handle)
+int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle)
 {
        return cast(handle)->get_refcount();
 }
 
-       
-void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC * handle)
+void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle)
 {
        return cast(handle)->get()->get_data();
 }
+
+void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
+                                            MEM_CacheLimiter_ItemPriority_Func item_priority_func)
+{
+       cast(This)->get_cache()->set_item_priority_func(item_priority_func);
+}
index 3e1368d8eb0624276a44393aecee3fb8c04c8882..de6d2c33b7f94a28b07eaab1861ab000c1503486 100644 (file)
@@ -33,8 +33,11 @@ set(INC_SYS
 
 set(SRC
        raskter.c
+       raskter_mt.c
+       raskter_kdtree.c
 
        raskter.h
+       raskter_kdtree.h
 )
 
 blender_add_lib(bf_intern_raskter "${SRC}" "${INC}" "${INC_SYS}")
index b405fde82e8fe25bce69bb593e3d3d540f90981e..7049f7d0ebe499d2947bcb5a24d617f507527074 100644 (file)
 
 #include <stdlib.h>
 #include "raskter.h"
+//#define __PLX__FAKE_AA__
+//#define __PLX_KD_TREE__
+#ifdef __PLX_KD_TREE__
+#include "kdtree.h"
+#endif
+
 
-#define __PLX__FAKE_AA__
-
-/* from BLI_utildefines.h */
-#define MIN2(x, y)      ( (x) < (y) ? (x) : (y) )
-#define MAX2(x, y)      ( (x) > (y) ? (x) : (y) )
-#define ABS(a)          ( (a) < 0 ? (-(a)) : (a) )
-
-struct e_status {
-       int x;
-       int ybeg;
-       int xshift;
-       int xdir;
-       int drift;
-       int drift_inc;
-       int drift_dec;
-       int num;
-       struct e_status *e_next;
-};
-
-struct r_buffer_stats {
-       float *buf;
-       int sizex;
-       int sizey;
-};
-
-struct r_fill_context {
-       struct e_status *all_edges, *possible_edges;
-       struct r_buffer_stats rb;
-};
 
 /*
  * Sort all the edges of the input polygon by Y, then by X, of the "first" vertex encountered.
@@ -69,102 +46,113 @@ struct r_fill_context {
  * just the poly. Since the DEM code could end up being coupled with this, we'll keep it separate
  * for now.
  */
-static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge)
-{
-       int i;
-       int xbeg;
-       int ybeg;
-       int xend;
-       int yend;
-       int dx;
-       int dy;
-       int temp_pos;
-       int xdist;
-       struct e_status *e_new;
-       struct e_status *next_edge;
-       struct e_status **next_edge_ref;
-       struct poly_vert *v;
-       /* set up pointers */
-       v = verts;
-       ctx->all_edges = NULL;
-       /* loop all verts */
-       for (i = 0; i < num_verts; i++) {
-               /* determine beginnings and endings of edges, linking last vertex to first vertex */
-               xbeg = v[i].x;
-               ybeg = v[i].y;
-               if (i) {
-                       /* we're not at the last vert, so end of the edge is the previous vertex */
-                       xend = v[i - 1].x;
-                       yend = v[i - 1].y;
-               }
-               else {
-                       /* we're at the first vertex, so the "end" of this edge is the last vertex */
-                       xend = v[num_verts - 1].x;
-                       yend = v[num_verts - 1].y;
-               }
-               /* make sure our edges are facing the correct direction */
-               if (ybeg > yend) {
-                       /* flip the Xs */
-                       temp_pos = xbeg;
-                       xbeg = xend;
-                       xend = temp_pos;
-                       /* flip the Ys */
-                       temp_pos = ybeg;
-                       ybeg = yend;
-                       yend = temp_pos;
-               }
-
-               /* calculate y delta */
-               dy = yend - ybeg;
-               /* dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) */
-               if (dy) {
-                       /* create the edge and determine it's slope (for incremental line drawing) */
-                       e_new = open_edge++;
-
-                       /* calculate x delta */
-                       dx = xend - xbeg;
-                       if (dx > 0) {
-                               e_new->xdir = 1;
-                               xdist = dx;
-                       }
-                       else {
-                               e_new->xdir = -1;
-                               xdist = -dx;
-                       }
-
-                       e_new->x = xbeg;
-                       e_new->ybeg = ybeg;
-                       e_new->num = dy;
-                       e_new->drift_dec = dy;
-
-                       /* calculate deltas for incremental drawing */
-                       if (dx >= 0) {
-                               e_new->drift = 0;
-                       }
-                       else {
-                               e_new->drift = -dy + 1;
-                       }
-                       if (dy >= xdist) {
-                               e_new->drift_inc = xdist;
-                               e_new->xshift = 0;
-                       }
-                       else {
-                               e_new->drift_inc = xdist % dy;
-                               e_new->xshift = (xdist / dy) * e_new->xdir;
-                       }
-                       next_edge_ref = &ctx->all_edges;
-                       /* link in all the edges, in sorted order */
-                       for (;; ) {
-                               next_edge = *next_edge_ref;
-                               if (!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) {
-                                       e_new->e_next = next_edge;
-                                       *next_edge_ref = e_new;
-                                       break;
-                               }
-                               next_edge_ref = &next_edge->e_next;
-                       }
-               }
-       }
+void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, struct e_status *open_edge) {
+    int i;
+    int xbeg;
+    int ybeg;
+    int xend;
+    int yend;
+    int dx;
+    int dy;
+    int temp_pos;
+    int xdist;
+    struct e_status *e_new;
+    struct e_status *next_edge;
+    struct e_status **next_edge_ref;
+    struct poly_vert *v;
+    /* set up pointers */
+    v = verts;
+    ctx->all_edges = NULL;
+    /* initialize some boundaries */
+    ctx->rb.xmax = v[0].x;
+    ctx->rb.xmin = v[0].x;
+    ctx->rb.ymax = v[0].y;
+    ctx->rb.ymin = v[0].y;
+    /* loop all verts */
+    for(i = 0; i < num_verts; i++) {
+        /* determine beginnings and endings of edges, linking last vertex to first vertex */
+        xbeg = v[i].x;
+        ybeg = v[i].y;
+        /* keep track of our x and y bounds */
+        if(xbeg >= ctx->rb.xmax) {
+            ctx->rb.xmax = xbeg;
+        } else if(xbeg <= ctx->rb.xmin) {
+            ctx->rb.xmin = xbeg;
+        }
+        if(ybeg >= ctx->rb.ymax) {
+            ctx->rb.ymax= ybeg;
+        } else if(ybeg <= ctx->rb.ymin) {
+            ctx->rb.ymin=ybeg;
+        }
+        if(i) {
+            /* we're not at the last vert, so end of the edge is the previous vertex */
+            xend = v[i - 1].x;
+            yend = v[i - 1].y;
+        } else {
+            /* we're at the first vertex, so the "end" of this edge is the last vertex */
+            xend = v[num_verts - 1].x;
+            yend = v[num_verts - 1].y;
+        }
+        /* make sure our edges are facing the correct direction */
+        if(ybeg > yend) {
+            /* flip the Xs */
+            temp_pos = xbeg;
+            xbeg = xend;
+            xend = temp_pos;
+            /* flip the Ys */
+            temp_pos = ybeg;
+            ybeg = yend;
+            yend = temp_pos;
+        }
+
+        /* calculate y delta */
+        dy = yend - ybeg;
+        /* dont draw horizontal lines directly, they are scanned as part of the edges they connect, so skip em. :) */
+        if(dy) {
+            /* create the edge and determine it's slope (for incremental line drawing) */
+            e_new = open_edge++;
+
+            /* calculate x delta */
+            dx = xend - xbeg;
+            if(dx > 0) {
+                e_new->xdir = 1;
+                xdist = dx;
+            } else {
+                e_new->xdir = -1;
+                xdist = -dx;
+            }
+
+            e_new->x = xbeg;
+            e_new->ybeg = ybeg;
+            e_new->num = dy;
+            e_new->drift_dec = dy;
+
+            /* calculate deltas for incremental drawing */
+            if(dx >= 0) {
+                e_new->drift = 0;
+            } else {
+                e_new->drift = -dy + 1;
+            }
+            if(dy >= xdist) {
+                e_new->drift_inc = xdist;
+                e_new->xshift = 0;
+            } else {
+                e_new->drift_inc = xdist % dy;
+                e_new->xshift = (xdist / dy) * e_new->xdir;
+            }
+            next_edge_ref = &ctx->all_edges;
+            /* link in all the edges, in sorted order */
+            for(;;) {
+                next_edge = *next_edge_ref;
+                if(!next_edge || (next_edge->ybeg > ybeg) || ((next_edge->ybeg == ybeg) && (next_edge->x >= xbeg))) {
+                    e_new->e_next = next_edge;
+                    *next_edge_ref = e_new;
+                    break;
+                }
+                next_edge_ref = &next_edge->e_next;
+            }
+        }
+    }
 }
 
 /*
@@ -172,281 +160,275 @@ static void preprocess_all_edges(struct r_fill_context *ctx, struct poly_vert *v
  * for speed, but waiting on final design choices for curve-data before eliminating data the DEM code will need
  * if it ends up being coupled with this function.
  */
-static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float intensity)
-{
-       int x_curr;                 /* current pixel position in X */
-       int y_curr;                 /* current scan line being drawn */
-       int yp;                     /* y-pixel's position in frame buffer */
-       int swixd = 0;              /* whether or not edges switched position in X */
-       float *cpxl;                /* pixel pointers... */
-       float *mpxl;
-       float *spxl;
-       struct e_status *e_curr;    /* edge pointers... */
-       struct e_status *e_temp;
-       struct e_status *edgbuf;
-       struct e_status **edgec;
-
-
-       /*
-        * If the number of verts specified to render as a polygon is less than 3,
-        * return immediately. Obviously we cant render a poly with sides < 3. The
-        * return for this we set to 1, simply so it can be distinguished from the
-        * next place we could return.
-        * which is a failure to allocate memory.
-        */
-       if (num_verts < 3) {
-               return(1);
-       }
-
-       /*
-        * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data
-        * multiplied by the number of edges, which is always equal to the number of verts in
-        * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for
-        * the preceeding error, which was a rasterization request on a 2D poly with less than
-        * 3 sides.
-        */
-       if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) {
-               return(0);
-       }
-
-       /*
-        * Do some preprocessing on all edges. This constructs a table structure in memory of all
-        * the edge properties and can "flip" some edges so sorting works correctly.
-        */
-       preprocess_all_edges(ctx, verts, num_verts, edgbuf);
-
-       /* can happen with a zero area mask */
-       if (ctx->all_edges == NULL) {
-               free(edgbuf);
-               return(1);
-       }
-
-       /*
-        * Set the pointer for tracking the edges currently in processing to NULL to make sure
-        * we don't get some crazy value after initialization.
-        */
-       ctx->possible_edges = NULL;
-
-       /*
-        * Loop through all scan lines to be drawn. Since we sorted by Y values during
-        * preprocess_all_edges(), we can already exact values for the lowest and
-        * highest Y values we could possibly need by induction. The preprocessing sorted
-        * out edges by Y position, we can cycle the current edge being processed once
-        * it runs out of Y pixels. When we have no more edges, meaning the current edge
-        * is NULL after setting the "current" edge to be the previous current edge's
-        * "next" edge in the Y sorted edge connection chain, we can stop looping Y values,
-        * since we can't possibly have more scan lines if we ran out of edges. :)
-        *
-        * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here.
-        *       Will get changed once DEM code gets in.
-        */
-       for (y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) {
-
-               /*
-                * Link any edges that start on the current scan line into the list of
-                * edges currently needed to draw at least this, if not several, scan lines.
-                */
-
-               /*
-                * Set the current edge to the beginning of the list of edges to be rasterized
-                * into this scan line.
-                *
-                * We could have lots of edge here, so iterate over all the edges needed. The
-                * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting
-                * so we safely cycle edges to thier own "next" edges in order.
-                *
-                * At each iteration, make sure we still have a non-NULL edge.
-                */
-               for (edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr); ) {
-                       x_curr = ctx->all_edges->x;                  /* Set current X position. */
-                       for (;; ) {                                  /* Start looping edges. Will break when edges run out. */
-                               e_curr = *edgec;                         /* Set up a current edge pointer. */
-                               if (!e_curr || (e_curr->x >= x_curr)) {  /* If we have an no edge, or we need to skip some X-span, */
-                                       e_temp = ctx->all_edges->e_next;     /* set a temp "next" edge to test. */
-                                       *edgec = ctx->all_edges;             /* Add this edge to the list to be scanned. */
-                                       ctx->all_edges->e_next = e_curr;     /* Set up the next edge. */
-                                       edgec = &ctx->all_edges->e_next;     /* Set our list to the next edge's location in memory. */
-                                       ctx->all_edges = e_temp;             /* Skip the NULL or bad X edge, set pointer to next edge. */
-                                       break;                               /* Stop looping edges (since we ran out or hit empty X span. */
-                               }
-                               else {
-                                       edgec = &e_curr->e_next;             /* Set the pointer to the edge list the "next" edge. */
-                               }
-                       }
-               }
-
-               /*
-                * Determine the current scan line's offset in the pixel buffer based on its Y position.
-                * Basically we just multiply the current scan line's Y value by the number of pixels in each line.
-                */
-               yp = y_curr * ctx->rb.sizex;
-               /*
-                * Set a "scan line pointer" in memory. The location of the buffer plus the row offset.
-                */
-               spxl = ctx->rb.buf + (yp);
-               /*
-                * Set up the current edge to the first (in X) edge. The edges which could possibly be in this
-                * list were determined in the preceeding edge loop above. They were already sorted in X by the
-                * initial processing function.
-                *
-                * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge
-                * we will eventually hit a NULL when the list runs out.
-                */
-               for (e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) {
-                       /*
-                        * Calculate a span of pixels to fill on the current scan line.
-                        *
-                        * Set the current pixel pointer by adding the X offset to the scan line's start offset.
-                        * Cycle the current edge the next edge.
-                        * Set the max X value to draw to be one less than the next edge's first pixel. This way we are
-                        * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than
-                        * one time because it's on a vertex connecting two edges)
-                        *
-                        * Then blast through all the pixels in the span, advancing the pointer and setting the color to white.
-                        *
-                        * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor,
-                        *       but for now it is done here until the DEM code comes in.
-                        */
-
-                       /* set up xmin and xmax bounds on this scan line */
-                       cpxl = spxl + MAX2(e_curr->x, 0);
-                       e_curr = e_curr->e_next;
-                       mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1;
-
-                       if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) {
-                               /* draw the pixels. */
-                               for(; cpxl <= mpxl; *cpxl++ += intensity);
-                       }
-               }
-
-               /*
-                * Loop through all edges of polygon that could be hit by this scan line,
-                * and figure out their x-intersections with the next scan line.
-                *
-                * Either A.) we wont have any more edges to test, or B.) we just add on the
-                * slope delta computed in preprocessing step. Since this draws non-antialiased
-                * polygons, we dont have fractional positions, so we only move in x-direction
-                * when needed to get all the way to the next pixel over...
-                */
-               for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) {
-                       if (!(--(e_curr->num))) {
-                               *edgec = e_curr->e_next;
-                       }
-                       else {
-                               e_curr->x += e_curr->xshift;
-                               if ((e_curr->drift += e_curr->drift_inc) > 0) {
-                                       e_curr->x += e_curr->xdir;
-                                       e_curr->drift -= e_curr->drift_dec;
-                               }
-                               edgec = &e_curr->e_next;
-                       }
-               }
-               /*
-                * It's possible that some edges may have crossed during the last step, so we'll be sure
-                * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges
-                * sorted by x-intersection coordinate. We'll always scan through at least once to see if
-                * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial
-                * pass, then we know we need to sort by x, so then cycle through edges again and perform
-                * the sort.-
-                */
-               if (ctx->possible_edges) {
-                       for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
-                               /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */
-                               if (e_curr->x > e_curr->e_next->x) {
-                                       *edgec = e_curr->e_next;
-                                       /* exchange the pointers */
-                                       e_temp = e_curr->e_next->e_next;
-                                       e_curr->e_next->e_next = e_curr;
-                                       e_curr->e_next = e_temp;
-                                       /* set flag that we had at least one switch */
-                                       swixd = 1;
-                               }
-                       }
-                       /* if we did have a switch, look for more (there will more if there was one) */
-                       for (;; ) {
-                               /* reset exchange flag so it's only set if we encounter another one */
-                               swixd = 0;
-                               for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
-                                       /* again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag */
-                                       if (e_curr->x > e_curr->e_next->x) {
-                                               *edgec = e_curr->e_next;
-                                               /* exchange the pointers */
-                                               e_temp = e_curr->e_next->e_next;
-                                               e_curr->e_next->e_next = e_curr;
-                                               e_curr->e_next = e_temp;
-                                               /* flip the exchanged flag */
-                                               swixd = 1;
-                                       }
-                               }
-                               /* if we had no exchanges, we're done reshuffling the pointers */
-                               if (!swixd) {
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       free(edgbuf);
-       return 1;
+static int rast_scan_fill(struct r_fill_context *ctx, struct poly_vert *verts, int num_verts, float intensity) {
+    int x_curr;                 /* current pixel position in X */
+    int y_curr;                 /* current scan line being drawn */
+    int yp;                     /* y-pixel's position in frame buffer */
+    int swixd = 0;              /* whether or not edges switched position in X */
+    float *cpxl;                /* pixel pointers... */
+    float *mpxl;
+    float *spxl;
+    struct e_status *e_curr;    /* edge pointers... */
+    struct e_status *e_temp;
+    struct e_status *edgbuf;
+    struct e_status **edgec;
+
+
+    /*
+     * If the number of verts specified to render as a polygon is less than 3,
+     * return immediately. Obviously we cant render a poly with sides < 3. The
+     * return for this we set to 1, simply so it can be distinguished from the
+     * next place we could return, /home/guest/blender-svn/soc-2011-tomato/intern/raskter/raskter.
+     * which is a failure to allocate memory.
+     */
+    if(num_verts < 3) {
+        return(1);
+    }
+
+    /*
+     * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data
+     * multiplied by the number of edges, which is always equal to the number of verts in
+     * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for
+     * the preceeding error, which was a rasterization request on a 2D poly with less than
+     * 3 sides.
+     */
+    if((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_verts))) == NULL) {
+        return(0);
+    }
+
+    /*
+     * Do some preprocessing on all edges. This constructs a table structure in memory of all
+     * the edge properties and can "flip" some edges so sorting works correctly.
+     */
+    preprocess_all_edges(ctx, verts, num_verts, edgbuf);
+
+    /* can happen with a zero area mask */
+    if (ctx->all_edges == NULL) {
+        free(edgbuf);
+        return(1);
+    }
+    /*
+     * Set the pointer for tracking the edges currently in processing to NULL to make sure
+     * we don't get some crazy value after initialization.
+     */
+    ctx->possible_edges = NULL;
+
+    /*
+     * Loop through all scan lines to be drawn. Since we sorted by Y values during
+     * preprocess_all_edges(), we can already exact values for the lowest and
+     * highest Y values we could possibly need by induction. The preprocessing sorted
+     * out edges by Y position, we can cycle the current edge being processed once
+     * it runs out of Y pixels. When we have no more edges, meaning the current edge
+     * is NULL after setting the "current" edge to be the previous current edge's
+     * "next" edge in the Y sorted edge connection chain, we can stop looping Y values,
+     * since we can't possibly have more scan lines if we ran out of edges. :)
+     *
+     * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here.
+     *       Will get changed once DEM code gets in.
+     */
+    for(y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) {
+
+        /*
+         * Link any edges that start on the current scan line into the list of
+         * edges currently needed to draw at least this, if not several, scan lines.
+         */
+
+        /*
+         * Set the current edge to the beginning of the list of edges to be rasterized
+         * into this scan line.
+         *
+         * We could have lots of edge here, so iterate over all the edges needed. The
+         * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting
+         * so we safely cycle edges to thier own "next" edges in order.
+         *
+         * At each iteration, make sure we still have a non-NULL edge.
+         */
+        for(edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr);) {
+            x_curr = ctx->all_edges->x;                  /* Set current X position. */
+            for(;;) {                                    /* Start looping edges. Will break when edges run out. */
+                e_curr = *edgec;                         /* Set up a current edge pointer. */
+                if(!e_curr || (e_curr->x >= x_curr)) {   /* If we have an no edge, or we need to skip some X-span, */
+                    e_temp = ctx->all_edges->e_next;     /* set a temp "next" edge to test. */
+                    *edgec = ctx->all_edges;             /* Add this edge to the list to be scanned. */
+                    ctx->all_edges->e_next = e_curr;     /* Set up the next edge. */
+                    edgec = &ctx->all_edges->e_next;     /* Set our list to the next edge's location in memory. */
+                    ctx->all_edges = e_temp;             /* Skip the NULL or bad X edge, set pointer to next edge. */
+                    break;                               /* Stop looping edges (since we ran out or hit empty X span. */
+                } else {
+                    edgec = &e_curr->e_next;             /* Set the pointer to the edge list the "next" edge. */
+                }
+            }
+        }
+
+        /*
+         * Determine the current scan line's offset in the pixel buffer based on its Y position.
+         * Basically we just multiply the current scan line's Y value by the number of pixels in each line.
+         */
+        yp = y_curr * ctx->rb.sizex;
+        /*
+         * Set a "scan line pointer" in memory. The location of the buffer plus the row offset.
+         */
+        spxl = ctx->rb.buf + (yp);
+        /*
+         * Set up the current edge to the first (in X) edge. The edges which could possibly be in this
+         * list were determined in the preceeding edge loop above. They were already sorted in X by the
+         * initial processing function.
+         *
+         * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge
+         * we will eventually hit a NULL when the list runs out.
+         */
+        for(e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) {
+            /*
+             * Calculate a span of pixels to fill on the current scan line.
+             *
+             * Set the current pixel pointer by adding the X offset to the scan line's start offset.
+             * Cycle the current edge the next edge.
+             * Set the max X value to draw to be one less than the next edge's first pixel. This way we are
+             * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than
+             * one time because it's on a vertex connecting two edges)
+             *
+             * Then blast through all the pixels in the span, advancing the pointer and setting the color to white.
+             *
+             * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor,
+             *       but for now it is done here until the DEM code comes in.
+             */
+
+            /* set up xmin and xmax bounds on this scan line */
+            cpxl = spxl + MAX2(e_curr->x, 0);
+            e_curr = e_curr->e_next;
+            mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1;
+
+            if((y_curr >= 0) && (y_curr < ctx->rb.sizey)) {
+                /* draw the pixels. */
+                for(; cpxl <= mpxl; *cpxl++ += intensity);
+            }
+        }
+
+        /*
+         * Loop through all edges of polygon that could be hit by this scan line,
+         * and figure out their x-intersections with the next scan line.
+         *
+         * Either A.) we wont have any more edges to test, or B.) we just add on the
+         * slope delta computed in preprocessing step. Since this draws non-antialiased
+         * polygons, we dont have fractional positions, so we only move in x-direction
+         * when needed to get all the way to the next pixel over...
+         */
+        for(edgec = &ctx->possible_edges; (e_curr = *edgec);) {
+            if(!(--(e_curr->num))) {
+                *edgec = e_curr->e_next;
+            } else {
+                e_curr->x += e_curr->xshift;
+                if((e_curr->drift += e_curr->drift_inc) > 0) {
+                    e_curr->x += e_curr->xdir;
+                    e_curr->drift -= e_curr->drift_dec;
+                }
+                edgec = &e_curr->e_next;
+            }
+        }
+        /*
+         * It's possible that some edges may have crossed during the last step, so we'll be sure
+         * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges
+         * sorted by x-intersection coordinate. We'll always scan through at least once to see if
+         * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial
+         * pass, then we know we need to sort by x, so then cycle through edges again and perform
+         * the sort.-
+         */
+        if(ctx->possible_edges) {
+            for(edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
+                /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */
+                if(e_curr->x > e_curr->e_next->x) {
+                    *edgec = e_curr->e_next;
+                    /* exchange the pointers */
+                    e_temp = e_curr->e_next->e_next;
+                    e_curr->e_next->e_next = e_curr;
+                    e_curr->e_next = e_temp;
+                    /* set flag that we had at least one switch */
+                    swixd = 1;
+                }
+            }
+            /* if we did have a switch, look for more (there will more if there was one) */
+            for(;;) {
+                /* reset exchange flag so it's only set if we encounter another one */
+                swixd = 0;
+                for(edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
+                    /* again, if current edge hits scan line at higher X than next edge, exchange the edges and set flag */
+                    if(e_curr->x > e_curr->e_next->x) {
+                        *edgec = e_curr->e_next;
+                        /* exchange the pointers */
+                        e_temp = e_curr->e_next->e_next;
+                        e_curr->e_next->e_next = e_curr;
+                        e_curr->e_next = e_temp;
+                        /* flip the exchanged flag */
+                        swixd = 1;
+                    }
+                }
+                /* if we had no exchanges, we're done reshuffling the pointers */
+                if(!swixd) {
+                    break;
+                }
+            }
+        }
+    }
+
+    free(edgbuf);
+    return 1;
 }
 
-int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
-                   float *buf, int buf_x, int buf_y, int do_mask_AA)
-{
-       int subdiv_AA = (do_mask_AA != 0) ? 8 : 0;
-       int i;                                   /* i: Loop counter. */
-       int sAx;
-       int sAy;
-       struct poly_vert *ply;                   /* ply: Pointer to a list of integer buffer-space vertex coordinates. */
-       struct r_fill_context ctx = {0};
-       const float buf_x_f = (float)(buf_x);
-       const float buf_y_f = (float)(buf_y);
-       float div_offset = (1.0f / (float)(subdiv_AA));
-       float div_offset_static = 0.5f * (float)(subdiv_AA) * div_offset;
-       /*
-        * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert
-        * data structure multiplied by the number of base_verts.
-        *
-        * In the event of a failure to allocate the memory, return 0, so this error can
-        * be distinguished as a memory allocation error.
-        */
-       if ((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_base_verts))) == NULL) {
-               return(0);
-       }
-
-       ctx.rb.buf = buf;                            /* Set the output buffer pointer. */
-       ctx.rb.sizex = buf_x;                        /* Set the output buffer size in X. (width) */
-       ctx.rb.sizey = buf_y;                        /* Set the output buffer size in Y. (height) */
-       /*
-        * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are
-        * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates
-        * in the buffer-space coordinates passed in inside buf_x and buf_y.
-        *
-        * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel
-        * drawn will be 1.0f in value, there is no anti-aliasing.
-        */
-
-       if (!subdiv_AA) {
-               for (i = 0; i < num_base_verts; i++) {                     /* Loop over all base_verts. */
-                       ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f); /* Range expand normalized X to integer buffer-space X. */
-                       ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */
-               }
-
-               i = rast_scan_fill(&ctx, ply, num_base_verts, 1.0f);  /* Call our rasterizer, passing in the integer coords for each vert. */
-       }
-       else {
-               for (sAx = 0; sAx < subdiv_AA; sAx++) {
-                       for (sAy = 0; sAy < subdiv_AA; sAy++) {
-                               for (i = 0; i < num_base_verts; i++) {
-                                       ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f - div_offset_static + (div_offset * (float)(sAx)));
-                                       ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f - div_offset_static + (div_offset * (float)(sAy)));
-                               }
-                               i = rast_scan_fill(&ctx, ply, num_base_verts, (1.0f / (float)(subdiv_AA * subdiv_AA)));
-                       }
-               }
-       }
-       free(ply);                                      /* Free the memory allocated for the integer coordinate table. */
-       return(i);                                      /* Return the value returned by the rasterizer. */
+int PLX_raskterize(float(*base_verts)[2], int num_base_verts,
+                   float *buf, int buf_x, int buf_y, int do_mask_AA) {
+    int subdiv_AA = (do_mask_AA != 0)? 0:0;
+    int i;                                   /* i: Loop counter. */
+    int sAx;
+    int sAy;
+    struct poly_vert *ply;                   /* ply: Pointer to a list of integer buffer-space vertex coordinates. */
+    struct r_fill_context ctx = {0};
+    const float buf_x_f = (float)(buf_x);
+    const float buf_y_f = (float)(buf_y);
+    float div_offset=(1.0f / (float)(subdiv_AA));
+    float div_offset_static = 0.5f * (float)(subdiv_AA) * div_offset;
+    /*
+     * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert
+     * data structure multiplied by the number of base_verts.
+     *
+     * In the event of a failure to allocate the memory, return 0, so this error can
+     * be distinguished as a memory allocation error.
+     */
+    if((ply = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_base_verts))) == NULL) {
+        return(0);
+    }
+
+    ctx.rb.buf = buf;                            /* Set the output buffer pointer. */
+    ctx.rb.sizex = buf_x;                        /* Set the output buffer size in X. (width) */
+    ctx.rb.sizey = buf_y;                        /* Set the output buffer size in Y. (height) */
+    /*
+     * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are
+     * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates
+     * in the buffer-space coordinates passed in inside buf_x and buf_y.
+     *
+     * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel
+     * drawn will be 1.0f in value, there is no anti-aliasing.
+     */
+
+    if(!subdiv_AA) {
+        for(i = 0; i < num_base_verts; i++) {                           /* Loop over all base_verts. */
+            ply[i].x = (int)((base_verts[i][0] * buf_x_f) + 0.5f);       /* Range expand normalized X to integer buffer-space X. */
+            ply[i].y = (int)((base_verts[i][1] * buf_y_f) + 0.5f); /* Range expand normalized Y to integer buffer-space Y. */
+        }
+
+        i = rast_scan_fill(&ctx, ply, num_base_verts,1.0f);  /* Call our rasterizer, passing in the integer coords for each vert. */
+    } else {
+        for(sAx=0; sAx < subdiv_AA; sAx++) {
+            for(sAy=0; sAy < subdiv_AA; sAy++) {
+                for(i=0; i < num_base_verts; i++) {
+                    ply[i].x = (int)((base_verts[i][0]*buf_x_f)+0.5f - div_offset_static + (div_offset*(float)(sAx)));
+                    ply[i].y = (int)((base_verts[i][1]*buf_y_f)+0.5f - div_offset_static + (div_offset*(float)(sAy)));
+                }
+                i = rast_scan_fill(&ctx, ply, num_base_verts,(1.0f / (float)(subdiv_AA*subdiv_AA)));
+            }
+        }
+    }
+    free(ply);                                      /* Free the memory allocated for the integer coordinate table. */
+    return(i);                                      /* Return the value returned by the rasterizer. */
 }
 
 /*
@@ -455,911 +437,1087 @@ int PLX_raskterize(float (*base_verts)[2], int num_base_verts,
  * if it ends up being coupled with this function.
  */
 static int rast_scan_feather(struct r_fill_context *ctx,
-                             float (*base_verts_f)[2], int num_base_verts,
-                             struct poly_vert *feather_verts, float(*feather_verts_f)[2], int num_feather_verts)
-{
-       int x_curr;                 /* current pixel position in X */
-       int y_curr;                 /* current scan line being drawn */
-       int yp;                     /* y-pixel's position in frame buffer */
-       int swixd = 0;              /* whether or not edges switched position in X */
-       float *cpxl;                /* pixel pointers... */
-       float *mpxl;
-       float *spxl;
-       struct e_status *e_curr;    /* edge pointers... */
-       struct e_status *e_temp;
-       struct e_status *edgbuf;
-       struct e_status **edgec;
-
-       /* from dem */
-       int a;                          // a = temporary pixel index buffer loop counter
-       float fsz;                        // size of the frame
-       unsigned int rsl;               // long used for finding fast 1.0/sqrt
-       float rsf;                      // float used for finding fast 1.0/sqrt
-       const float rsopf = 1.5f;       // constant float used for finding fast 1.0/sqrt
-
-       //unsigned int gradientFillOffset;
-       float t;
-       float ud;                // ud = unscaled edge distance
-       float dmin;              // dmin = minimun edge distance
-       float odist;                    // odist = current outer edge distance
-       float idist;                    // idist = current inner edge distance
-       float dx;                         // dx = X-delta (used for distance proportion calculation)
-       float dy;                         // dy = Y-delta (used for distance proportion calculation)
-       float xpxw = (1.0f / (float)(ctx->rb.sizex));  // xpxw = normalized pixel width
-       float ypxh = (1.0f / (float)(ctx->rb.sizey));  // ypxh = normalized pixel height
-
-       /*
-        * If the number of verts specified to render as a polygon is less than 3,
-        * return immediately. Obviously we cant render a poly with sides < 3. The
-        * return for this we set to 1, simply so it can be distinguished from the
-        * next place we could return,
-        * which is a failure to allocate memory.
-        */
-       if (num_feather_verts < 3) {
-               return(1);
-       }
-
-       /*
-        * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data
-        * multiplied by the number of edges, which is always equal to the number of verts in
-        * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for
-        * the preceeding error, which was a rasterization request on a 2D poly with less than
-        * 3 sides.
-        */
-       if ((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_feather_verts))) == NULL) {
-               return(0);
-       }
-
-       /*
-        * Do some preprocessing on all edges. This constructs a table structure in memory of all
-        * the edge properties and can "flip" some edges so sorting works correctly.
-        */
-       preprocess_all_edges(ctx, feather_verts, num_feather_verts, edgbuf);
-
-       /* can happen with a zero area mask */
-       if (ctx->all_edges == NULL) {
-               free(edgbuf);
-               return(1);
-       }
-
-       /*
-        * Set the pointer for tracking the edges currently in processing to NULL to make sure
-        * we don't get some crazy value after initialization.
-        */
-       ctx->possible_edges = NULL;
-
-       /*
-        * Loop through all scan lines to be drawn. Since we sorted by Y values during
-        * preprocess_all_edges(), we can already exact values for the lowest and
-        * highest Y values we could possibly need by induction. The preprocessing sorted
-        * out edges by Y position, we can cycle the current edge being processed once
-        * it runs out of Y pixels. When we have no more edges, meaning the current edge
-        * is NULL after setting the "current" edge to be the previous current edge's
-        * "next" edge in the Y sorted edge connection chain, we can stop looping Y values,
-        * since we can't possibly have more scan lines if we ran out of edges. :)
-        *
-        * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here.
-        *       Will get changed once DEM code gets in.
-        */
-       for (y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) {
-
-               /*
-                * Link any edges that start on the current scan line into the list of
-                * edges currently needed to draw at least this, if not several, scan lines.
-                */
-
-               /*
-                * Set the current edge to the beginning of the list of edges to be rasterized
-                * into this scan line.
-                *
-                * We could have lots of edge here, so iterate over all the edges needed. The
-                * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting
-                * so we safely cycle edges to thier own "next" edges in order.
-                *
-                * At each iteration, make sure we still have a non-NULL edge.
-                */
-               for (edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr); ) {
-                       x_curr = ctx->all_edges->x;                  /* Set current X position. */
-                       for (;; ) {                                  /* Start looping edges. Will break when edges run out. */
-                               e_curr = *edgec;                         /* Set up a current edge pointer. */
-                               if (!e_curr || (e_curr->x >= x_curr)) {  /* If we have an no edge, or we need to skip some X-span, */
-                                       e_temp = ctx->all_edges->e_next;     /* set a temp "next" edge to test. */
-                                       *edgec = ctx->all_edges;             /* Add this edge to the list to be scanned. */
-                                       ctx->all_edges->e_next = e_curr;     /* Set up the next edge. */
-                                       edgec = &ctx->all_edges->e_next;     /* Set our list to the next edge's location in memory. */
-                                       ctx->all_edges = e_temp;             /* Skip the NULL or bad X edge, set pointer to next edge. */
-                                       break;                               /* Stop looping edges (since we ran out or hit empty X span. */
-                               }
-                               else {
-                                       edgec = &e_curr->e_next;             /* Set the pointer to the edge list the "next" edge. */
-                               }
-                       }
-               }
-
-               /*
-                * Determine the current scan line's offset in the pixel buffer based on its Y position.
-                * Basically we just multiply the current scan line's Y value by the number of pixels in each line.
-                */
-               yp = y_curr * ctx->rb.sizex;
-               /*
-                * Set a "scan line pointer" in memory. The location of the buffer plus the row offset.
-                */
-               spxl = ctx->rb.buf + (yp);
-               /*
-                * Set up the current edge to the first (in X) edge. The edges which could possibly be in this
-                * list were determined in the preceeding edge loop above. They were already sorted in X by the
-                * initial processing function.
-                *
-                * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge
-                * we will eventually hit a NULL when the list runs out.
-                */
-               for (e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) {
-                       /*
-                        * Calculate a span of pixels to fill on the current scan line.
-                        *
-                        * Set the current pixel pointer by adding the X offset to the scan line's start offset.
-                        * Cycle the current edge the next edge.
-                        * Set the max X value to draw to be one less than the next edge's first pixel. This way we are
-                        * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than
-                        * one time because it's on a vertex connecting two edges)
-                        *
-                        * Then blast through all the pixels in the span, advancing the pointer and setting the color to white.
-                        *
-                        * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor,
-                        *       but for now it is done here until the DEM code comes in.
-                        */
-
-                       /* set up xmin and xmax bounds on this scan line */
-                       cpxl = spxl + MAX2(e_curr->x, 0);
-                       e_curr = e_curr->e_next;
-                       mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1;
-
-                       if ((y_curr >= 0) && (y_curr < ctx->rb.sizey)) {
-                               t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * xpxw;
-                               fsz = ((float)(y_curr) + 0.5f) * ypxh;
-                               /* draw the pixels. */
-                               for (; cpxl <= mpxl; cpxl++, t += xpxw) {
-                                       //do feather check
-                                       // first check that pixel isn't already full, and only operate if it is not
-                                       if (*cpxl < 0.9999f) {
-
-                                               dmin = 2.0f;                        // reset min distance to edge pixel
-                                               for (a = 0; a < num_feather_verts; a++) { // loop through all outer edge buffer pixels
-                                                       dy = t - feather_verts_f[a][0];          // set dx to gradient pixel column - outer edge pixel row
-                                                       dx = fsz - feather_verts_f[a][1];        // set dy to gradient pixel row - outer edge pixel column
-                                                       ud = dx * dx + dy * dy;               // compute sum of squares
-                                                       if (ud < dmin) {                      // if our new sum of squares is less than the current minimum
-                                                               dmin = ud;                        // set a new minimum equal to the new lower value
-                                                       }
-                                               }
-                                               odist = dmin;                    // cast outer min to a float
-                                               rsf = odist * 0.5f;                       //
-                                               rsl = *(unsigned int *)&odist;            // use some peculiar properties of the way bits are stored
-                                               rsl = 0x5f3759df - (rsl >> 1);            // in floats vs. unsigned ints to compute an approximate
-                                               odist = *(float *)&rsl;                   // reciprocal square root
-                                               odist = odist * (rsopf - (rsf * odist * odist));  // -- ** this line can be iterated for more accuracy ** --
-                                               odist = odist * (rsopf - (rsf * odist * odist));
-                                               dmin = 2.0f;                        // reset min distance to edge pixel
-                                               for (a = 0; a < num_base_verts; a++) {    // loop through all inside edge pixels
-                                                       dy = t - base_verts_f[a][0];             // compute delta in Y from gradient pixel to inside edge pixel
-                                                       dx = fsz - base_verts_f[a][1];           // compute delta in X from gradient pixel to inside edge pixel
-                                                       ud = dx * dx + dy * dy;   // compute sum of squares
-                                                       if (ud < dmin) {          // if our new sum of squares is less than the current minimum we've found
-                                                               dmin = ud;            // set a new minimum equal to the new lower value
-                                                       }
-                                               }
-                                               idist = dmin;                    // cast inner min to a float
-                                               rsf = idist * 0.5f;                       //
-                                               rsl = *(unsigned int *)&idist;            //
-                                               rsl = 0x5f3759df - (rsl >> 1);            // see notes above
-                                               idist = *(float *)&rsl;                   //
-                                               idist = idist * (rsopf - (rsf * idist * idist));  //
-                                               idist = idist * (rsopf - (rsf * idist * idist));
-                                               /*
-                                                * Note once again that since we are using reciprocals of distance values our
-                                                * proportion is already the correct intensity, and does not need to be
-                                                * subracted from 1.0 like it would have if we used real distances.
-                                                */
-
-                                               /* set intensity, do the += so overlapping gradients are additive */
-                                               *cpxl = (idist / (idist + odist));
-                                       }
-                               }
-                       }
-               }
-
-               /*
-                * Loop through all edges of polygon that could be hit by this scan line,
-                * and figure out their x-intersections with the next scan line.
-                *
-                * Either A.) we wont have any more edges to test, or B.) we just add on the
-                * slope delta computed in preprocessing step. Since this draws non-antialiased
-                * polygons, we dont have fractional positions, so we only move in x-direction
-                * when needed to get all the way to the next pixel over...
-                */
-               for (edgec = &ctx->possible_edges; (e_curr = *edgec); ) {
-                       if (!(--(e_curr->num))) {
-                               *edgec = e_curr->e_next;
-                       }
-                       else {
-                               e_curr->x += e_curr->xshift;
-                               if ((e_curr->drift += e_curr->drift_inc) > 0) {
-                                       e_curr->x += e_curr->xdir;
-                                       e_curr->drift -= e_curr->drift_dec;
-                               }
-                               edgec = &e_curr->e_next;
-                       }
-               }
-               /*
-                * It's possible that some edges may have crossed during the last step, so we'll be sure
-                * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges
-                * sorted by x-intersection coordinate. We'll always scan through at least once to see if
-                * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial
-                * pass, then we know we need to sort by x, so then cycle through edges again and perform
-                * the sort.-
-                */
-               if (ctx->possible_edges) {
-                       for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
-                               /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */
-                               if (e_curr->x > e_curr->e_next->x) {
-                                       *edgec = e_curr->e_next;
-                                       /* exchange the pointers */
-                                       e_temp = e_curr->e_next->e_next;
-                                       e_curr->e_next->e_next = e_curr;
-                                       e_curr->e_next = e_temp;
-                                       /* set flag that we had at least one switch */
-                                       swixd = 1;
-                               }
-                       }
-                       /* if we did have a switch, look for more (there will more if there was one) */
-                       for (;; ) {
-                               /* reset exchange flag so it's only set if we encounter another one */
-                               swixd = 0;
-                               for (edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
-                                       /* again, if current edge hits scan line at higher X than next edge,
-                                        * exchange the edges and set flag */
-                                       if (e_curr->x > e_curr->e_next->x) {
-                                               *edgec = e_curr->e_next;
-                                               /* exchange the pointers */
-                                               e_temp = e_curr->e_next->e_next;
-                                               e_curr->e_next->e_next = e_curr;
-                                               e_curr->e_next = e_temp;
-                                               /* flip the exchanged flag */
-                                               swixd = 1;
-                                       }
-                               }
-                               /* if we had no exchanges, we're done reshuffling the pointers */
-                               if (!swixd) {
-                                       break;
-                               }
-                       }
-               }
-       }
-
-       free(edgbuf);
-       return 1;
+                             float(*base_verts_f)[2], int num_base_verts,
+                             struct poly_vert *feather_verts, float(*feather_verts_f)[2], int num_feather_verts) {
+    int x_curr;                 /* current pixel position in X */
+    int y_curr;                 /* current scan line being drawn */
+    int yp;                     /* y-pixel's position in frame buffer */
+    int swixd = 0;              /* whether or not edges switched position in X */
+    float *cpxl;                /* pixel pointers... */
+    float *mpxl;
+    float *spxl;
+    struct e_status *e_curr;    /* edge pointers... */
+    struct e_status *e_temp;
+    struct e_status *edgbuf;
+    struct e_status **edgec;
+
+    /* from dem */
+    int a;                          // a = temporary pixel index buffer loop counter
+    float fsz;                        // size of the frame
+    unsigned int rsl;               // long used for finding fast 1.0/sqrt
+    float rsf;                      // float used for finding fast 1.0/sqrt
+    const float rsopf = 1.5f;       // constant float used for finding fast 1.0/sqrt
+
+    //unsigned int gradientFillOffset;
+    float t;
+    float ud;                // ud = unscaled edge distance
+    float dmin;              // dmin = minimun edge distance
+    float odist;                    // odist = current outer edge distance
+    float idist;                    // idist = current inner edge distance
+    float dx;                         // dx = X-delta (used for distance proportion calculation)
+    float dy;                         // dy = Y-delta (used for distance proportion calculation)
+    float xpxw = (1.0f / (float)(ctx->rb.sizex));  // xpxw = normalized pixel width
+    float ypxh = (1.0f / (float)(ctx->rb.sizey));  // ypxh = normalized pixel height
+#ifdef __PLX_KD_TREE__
+    void *res_kdi;
+    void *res_kdo;
+    float clup[2];
+#endif
+
+    /*
+     * If the number of verts specified to render as a polygon is less than 3,
+     * return immediately. Obviously we cant render a poly with sides < 3. The
+     * return for this we set to 1, simply so it can be distinguished from the
+     * next place we could return,
+     * which is a failure to allocate memory.
+     */
+    if(num_feather_verts < 3) {
+        return(1);
+    }
+
+    /*
+     * Try to allocate an edge buffer in memory. needs to be the size of the edge tracking data
+     * multiplied by the number of edges, which is always equal to the number of verts in
+     * a 2D polygon. Here we return 0 to indicate a memory allocation failure, as opposed to a 1 for
+     * the preceeding error, which was a rasterization request on a 2D poly with less than
+     * 3 sides.
+     */
+    if((edgbuf = (struct e_status *)(malloc(sizeof(struct e_status) * num_feather_verts))) == NULL) {
+        return(0);
+    }
+
+    /*
+     * Do some preprocessing on all edges. This constructs a table structure in memory of all
+     * the edge properties and can "flip" some edges so sorting works correctly.
+     */
+    preprocess_all_edges(ctx, feather_verts, num_feather_verts, edgbuf);
+
+    /* can happen with a zero area mask */
+    if (ctx->all_edges == NULL) {
+        free(edgbuf);
+        return(1);
+    }
+
+    /*
+     * Set the pointer for tracking the edges currently in processing to NULL to make sure
+     * we don't get some crazy value after initialization.
+     */
+    ctx->possible_edges = NULL;
+
+    /*
+     * Loop through all scan lines to be drawn. Since we sorted by Y values during
+     * preprocess_all_edges(), we can already exact values for the lowest and
+     * highest Y values we could possibly need by induction. The preprocessing sorted
+     * out edges by Y position, we can cycle the current edge being processed once
+     * it runs out of Y pixels. When we have no more edges, meaning the current edge
+     * is NULL after setting the "current" edge to be the previous current edge's
+     * "next" edge in the Y sorted edge connection chain, we can stop looping Y values,
+     * since we can't possibly have more scan lines if we ran out of edges. :)
+     *
+     * TODO: This clips Y to the frame buffer, which should be done in the preprocessor, but for now is done here.
+     *       Will get changed once DEM code gets in.
+     */
+    for(y_curr = ctx->all_edges->ybeg; (ctx->all_edges || ctx->possible_edges); y_curr++) {
+
+        /*
+         * Link any edges that start on the current scan line into the list of
+         * edges currently needed to draw at least this, if not several, scan lines.
+         */
+
+        /*
+         * Set the current edge to the beginning of the list of edges to be rasterized
+         * into this scan line.
+         *
+         * We could have lots of edge here, so iterate over all the edges needed. The
+         * preprocess_all_edges() function sorted edges by X within each chunk of Y sorting
+         * so we safely cycle edges to thier own "next" edges in order.
+         *
+         * At each iteration, make sure we still have a non-NULL edge.
+         */
+        for(edgec = &ctx->possible_edges; ctx->all_edges && (ctx->all_edges->ybeg == y_curr);) {
+            x_curr = ctx->all_edges->x;                  /* Set current X position. */
+            for(;;) {                                    /* Start looping edges. Will break when edges run out. */
+                e_curr = *edgec;                         /* Set up a current edge pointer. */
+                if(!e_curr || (e_curr->x >= x_curr)) {   /* If we have an no edge, or we need to skip some X-span, */
+                    e_temp = ctx->all_edges->e_next;     /* set a temp "next" edge to test. */
+                    *edgec = ctx->all_edges;             /* Add this edge to the list to be scanned. */
+                    ctx->all_edges->e_next = e_curr;     /* Set up the next edge. */
+                    edgec = &ctx->all_edges->e_next;     /* Set our list to the next edge's location in memory. */
+                    ctx->all_edges = e_temp;             /* Skip the NULL or bad X edge, set pointer to next edge. */
+                    break;                               /* Stop looping edges (since we ran out or hit empty X span. */
+                } else {
+                    edgec = &e_curr->e_next;             /* Set the pointer to the edge list the "next" edge. */
+                }
+            }
+        }
+
+        /*
+         * Determine the current scan line's offset in the pixel buffer based on its Y position.
+         * Basically we just multiply the current scan line's Y value by the number of pixels in each line.
+         */
+        yp = y_curr * ctx->rb.sizex;
+        /*
+         * Set a "scan line pointer" in memory. The location of the buffer plus the row offset.
+         */
+        spxl = ctx->rb.buf + (yp);
+        /*
+         * Set up the current edge to the first (in X) edge. The edges which could possibly be in this
+         * list were determined in the preceeding edge loop above. They were already sorted in X by the
+         * initial processing function.
+         *
+         * At each iteration, test for a NULL edge. Since we'll keep cycling edge's to their own "next" edge
+         * we will eventually hit a NULL when the list runs out.
+         */
+        for(e_curr = ctx->possible_edges; e_curr; e_curr = e_curr->e_next) {
+            /*
+             * Calculate a span of pixels to fill on the current scan line.
+             *
+             * Set the current pixel pointer by adding the X offset to the scan line's start offset.
+             * Cycle the current edge the next edge.
+             * Set the max X value to draw to be one less than the next edge's first pixel. This way we are
+             * sure not to ever get into a situation where we have overdraw. (drawing the same pixel more than
+             * one time because it's on a vertex connecting two edges)
+             *
+             * Then blast through all the pixels in the span, advancing the pointer and setting the color to white.
+             *
+             * TODO: Here we clip to the scan line, this is not efficient, and should be done in the preprocessor,
+             *       but for now it is done here until the DEM code comes in.
+             */
+
+            /* set up xmin and xmax bounds on this scan line */
+            cpxl = spxl + MAX2(e_curr->x, 0);
+            e_curr = e_curr->e_next;
+            mpxl = spxl + MIN2(e_curr->x, ctx->rb.sizex) - 1;
+
+            if((y_curr >= 0) && (y_curr < ctx->rb.sizey)) {
+                t = ((float)((cpxl - spxl) % ctx->rb.sizex) + 0.5f) * xpxw;
+                fsz = ((float)(y_curr) + 0.5f) * ypxh;
+                /* draw the pixels. */
+                for(; cpxl <= mpxl; cpxl++, t += xpxw) {
+                    //do feather check
+                    // first check that pixel isn't already full, and only operate if it is not
+                    if(*cpxl < 0.9999f) {
+#ifndef __PLX_KD_TREE__
+                        dmin = 2.0f;                        // reset min distance to edge pixel
+                        for(a = 0; a < num_feather_verts; a++) {  // loop through all outer edge buffer pixels
+                            dx = t - feather_verts_f[a][0];          // set dx to gradient pixel column - outer edge pixel row
+                            dy = fsz - feather_verts_f[a][1];        // set dy to gradient pixel row - outer edge pixel column
+                            ud = dx * dx + dy * dy;               // compute sum of squares
+                            if(ud < dmin) {                       // if our new sum of squares is less than the current minimum
+                                dmin = ud;                        // set a new minimum equal to the new lower value
+                            }
+                        }
+                        odist = dmin;                    // cast outer min to a float
+                        rsf = odist * 0.5f;                       //
+                        rsl = *(unsigned int *)&odist;            // use some peculiar properties of the way bits are stored
+                        rsl = 0x5f3759df - (rsl >> 1);            // in floats vs. unsigned ints to compute an approximate
+                        odist = *(float *)&rsl;                   // reciprocal square root
+                        odist = odist * (rsopf - (rsf * odist * odist));  // -- ** this line can be iterated for more accuracy ** --
+                        odist = odist * (rsopf - (rsf * odist * odist));
+                        dmin = 2.0f;                        // reset min distance to edge pixel
+                        for(a = 0; a < num_base_verts; a++) {     // loop through all inside edge pixels
+                            dx = t - base_verts_f[a][0];             // compute delta in Y from gradient pixel to inside edge pixel
+                            dy = fsz - base_verts_f[a][1];           // compute delta in X from gradient pixel to inside edge pixel
+                            ud = dx * dx + dy * dy;   // compute sum of squares
+                            if(ud < dmin) {           // if our new sum of squares is less than the current minimum we've found
+                                dmin = ud;            // set a new minimum equal to the new lower value
+                            }
+                        }
+                        idist = dmin;                    // cast inner min to a float
+                        rsf = idist * 0.5f;                       //
+                        rsl = *(unsigned int *)&idist;            //
+                        rsl = 0x5f3759df - (rsl >> 1);            // see notes above
+                        idist = *(float *)&rsl;                   //
+                        idist = idist * (rsopf - (rsf * idist * idist));  //
+                        idist = idist * (rsopf - (rsf * idist * idist));
+                        /*
+                         * Note once again that since we are using reciprocals of distance values our
+                         * proportion is already the correct intensity, and does not need to be
+                         * subracted from 1.0 like it would have if we used real distances.
+                         */
+#else
+                        clup[0]=t;
+                        clup[1]=fsz;
+                        res_kdi=kd_nearestf(ctx->kdi,clup);
+                        res_kdo=kd_nearestf(ctx->kdo,clup);
+                        kd_res_itemf(res_kdi,clup);
+                        dx=t-clup[0];
+                        dy=fsz-clup[1];
+                        idist=dx*dx+dy*dy;
+                        rsf = idist * 0.5f;                       //
+                        rsl = *(unsigned int *)&idist;            //
+                        rsl = 0x5f3759df - (rsl >> 1);            // see notes above
+                        idist = *(float *)&rsl;                   //
+                        idist = idist * (rsopf - (rsf * idist * idist));  //
+                        idist = idist * (rsopf - (rsf * idist * idist));
+                        kd_res_itemf(res_kdo,clup);
+                        dx=t-clup[0];
+                        dy=fsz-clup[1];
+                        odist=dx*dx+dy*dy;
+                        rsf = odist * 0.5f;                       //
+                        rsl = *(unsigned int *)&odist;            // use some peculiar properties of the way bits are stored
+                        rsl = 0x5f3759df - (rsl >> 1);            // in floats vs. unsigned ints to compute an approximate
+                        odist = *(float *)&rsl;                   // reciprocal square root
+                        odist = odist * (rsopf - (rsf * odist * odist));  // -- ** this line can be iterated for more accuracy ** --
+                        odist = odist * (rsopf - (rsf * odist * odist));
+
+#endif
+                        /* set intensity, do the += so overlapping gradients are additive */
+                        *cpxl = (idist / (idist+odist));
+                    }
+                }
+            }
+        }
+
+        /*
+         * Loop through all edges of polygon that could be hit by this scan line,
+         * and figure out their x-intersections with the next scan line.
+         *
+         * Either A.) we wont have any more edges to test, or B.) we just add on the
+         * slope delta computed in preprocessing step. Since this draws non-antialiased
+         * polygons, we dont have fractional positions, so we only move in x-direction
+         * when needed to get all the way to the next pixel over...
+         */
+        for(edgec = &ctx->possible_edges; (e_curr = *edgec);) {
+            if(!(--(e_curr->num))) {
+                *edgec = e_curr->e_next;
+            } else {
+                e_curr->x += e_curr->xshift;
+                if((e_curr->drift += e_curr->drift_inc) > 0) {
+                    e_curr->x += e_curr->xdir;
+                    e_curr->drift -= e_curr->drift_dec;
+                }
+                edgec = &e_curr->e_next;
+            }
+        }
+        /*
+         * It's possible that some edges may have crossed during the last step, so we'll be sure
+         * that we ALWAYS intersect scan lines in order by shuffling if needed to make all edges
+         * sorted by x-intersection coordinate. We'll always scan through at least once to see if
+         * edges crossed, and if so, we set the 'swixd' flag. If 'swixd' gets set on the initial
+         * pass, then we know we need to sort by x, so then cycle through edges again and perform
+         * the sort.-
+         */
+        if(ctx->possible_edges) {
+            for(edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
+                /* if the current edge hits scan line at greater X than the next edge, we need to exchange the edges */
+                if(e_curr->x > e_curr->e_next->x) {
+                    *edgec = e_curr->e_next;
+                    /* exchange the pointers */
+                    e_temp = e_curr->e_next->e_next;
+                    e_curr->e_next->e_next = e_curr;
+                    e_curr->e_next = e_temp;
+                    /* set flag that we had at least one switch */
+                    swixd = 1;
+                }
+            }
+            /* if we did have a switch, look for more (there will more if there was one) */
+            for(;;) {
+                /* reset exchange flag so it's only set if we encounter another one */
+                swixd = 0;
+                for(edgec = &ctx->possible_edges; (e_curr = *edgec)->e_next; edgec = &(*edgec)->e_next) {
+                    /* again, if current edge hits scan line at higher X than next edge,
+                     * exchange the edges and set flag */
+                    if(e_curr->x > e_curr->e_next->x) {
+                        *edgec = e_curr->e_next;
+                        /* exchange the pointers */
+                        e_temp = e_curr->e_next->e_next;
+                        e_curr->e_next->e_next = e_curr;
+                        e_curr->e_next = e_temp;
+                        /* flip the exchanged flag */
+                        swixd = 1;
+                    }
+                }
+                /* if we had no exchanges, we're done reshuffling the pointers */
+                if(!swixd) {
+                    break;
+                }
+            }
+        }
+    }
+
+    free(edgbuf);
+    return 1;
 }
 
-int PLX_raskterize_feather(float (*base_verts)[2], int num_base_verts, float (*feather_verts)[2], int num_feather_verts,
-                                                  float *buf, int buf_x, int buf_y) {
-       int i;                            /* i: Loop counter. */
-       struct poly_vert *fe;             /* fe: Pointer to a list of integer buffer-space feather vertex coords. */
-       struct r_fill_context ctx = {0};
-
-       /* for faster multiply */
-       const float buf_x_f = (float)buf_x;
-       const float buf_y_f = (float)buf_y;
-
-       /*
-        * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert
-        * data structure multiplied by the number of verts.
-        *
-        * In the event of a failure to allocate the memory, return 0, so this error can
-        * be distinguished as a memory allocation error.
-        */
-       if ((fe = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_feather_verts))) == NULL) {
-               return(0);
-       }
-
-       /*
-        * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are
-        * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates
-        * in the buffer-space coordinates passed in inside buf_x and buf_y.
-        *
-        * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel
-        * drawn will be 1.0f in value, there is no anti-aliasing.
-        */
-       for (i = 0; i < num_feather_verts; i++) {            /* Loop over all verts. */
-               fe[i].x = (int)((feather_verts[i][0] * buf_x_f) + 0.5f);  /* Range expand normalized X to integer buffer-space X. */
-               fe[i].y = (int)((feather_verts[i][1] * buf_y_f) + 0.5f);  /* Range expand normalized Y to integer buffer-space Y. */
-       }
-
-       ctx.rb.buf = buf;                            /* Set the output buffer pointer. */
-       ctx.rb.sizex = buf_x;                        /* Set the output buffer size in X. (width) */
-       ctx.rb.sizey = buf_y;                        /* Set the output buffer size in Y. (height) */
-
-       /* Call our rasterizer, passing in the integer coords for each vert. */
-       i = rast_scan_feather(&ctx, base_verts, num_base_verts, fe, feather_verts, num_feather_verts);
-       free(fe);
-       return i;                                   /* Return the value returned by the rasterizer. */
+int PLX_raskterize_feather(float(*base_verts)[2], int num_base_verts, float(*feather_verts)[2], int num_feather_verts,
+                           float *buf, int buf_x, int buf_y) {
+    //void plx_floatsort(float(*f)[2], unsigned int n, int sortby);
+    int i;                            /* i: Loop counter. */
+    struct poly_vert *fe;             /* fe: Pointer to a list of integer buffer-space feather vertex coords. */
+    struct r_fill_context ctx = {0};
+
+    /* for faster multiply */
+    const float buf_x_f = (float)buf_x;
+    const float buf_y_f = (float)buf_y;
+#ifdef __PLX_KD_TREE__
+    ctx.kdi = kd_create(2);
+    ctx.kdo = kd_create(2);
+#endif
+    /*
+     * Allocate enough memory for our poly_vert list. It'll be the size of the poly_vert
+     * data structure multiplied by the number of verts.
+     *
+     * In the event of a failure to allocate the memory, return 0, so this error can
+     * be distinguished as a memory allocation error.
+     */
+    if((fe = (struct poly_vert *)(malloc(sizeof(struct poly_vert) * num_feather_verts))) == NULL) {
+        return(0);
+    }
+
+    /*
+     * Loop over all verts passed in to be rasterized. Each vertex's X and Y coordinates are
+     * then converted from normalized screen space (0.0 <= POS <= 1.0) to integer coordinates
+     * in the buffer-space coordinates passed in inside buf_x and buf_y.
+     *
+     * It's worth noting that this function ONLY outputs fully white pixels in a mask. Every pixel
+     * drawn will be 1.0f in value, there is no anti-aliasing.
+     */
+    for(i = 0; i < num_feather_verts; i++) {             /* Loop over all verts. */
+        fe[i].x = (int)((feather_verts[i][0] * buf_x_f) + 0.5f);  /* Range expand normalized X to integer buffer-space X. */
+        fe[i].y = (int)((feather_verts[i][1] * buf_y_f) + 0.5f);  /* Range expand normalized Y to integer buffer-space Y. */
+#ifdef __PLX_KD_TREE__
+        kd_insertf(ctx.kdo,feather_verts[i],NULL);
+    }
+    for(i=0;i<num_base_verts;i++){
+        kd_insertf(ctx.kdi,base_verts[i],NULL);
+#endif
+    }
+
+    ctx.rb.buf = buf;                            /* Set the output buffer pointer. */
+    ctx.rb.sizex = buf_x;                        /* Set the output buffer size in X. (width) */
+    ctx.rb.sizey = buf_y;                        /* Set the output buffer size in Y. (height) */
+    /* pre-sort the sets of edge verts on y */
+    //plx_floatsort(base_verts,num_base_verts,0);
+    //plx_floatsort(base_verts,num_base_verts,1);
+    //plx_floatsort(feather_verts,num_feather_verts,0);
+    //plx_floatsort(feather_verts,num_feather_verts,1);
+    /* Call our rasterizer, passing in the integer coords for each vert. */
+    i = rast_scan_feather(&ctx, base_verts, num_base_verts, fe, feather_verts, num_feather_verts);
+    free(fe);
+    return i;                                   /* Return the value returned by the rasterizer. */
 }
 
 #ifndef __PLX__FAKE_AA__
 
-static int get_range_expanded_pixel_coord(float normalized_value, int max_value)
-{
-       return (int)((normalized_value * (float)(max_value)) + 0.5f);
+int get_range_expanded_pixel_coord(float normalized_value, int max_value) {
+    return (int)((normalized_value * (float)(max_value)) + 0.5f);
 }
 
-static float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y)
-{
-       if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
-               return 0.0f;
-       }
-       return buf[(pos_y * buf_y) + buf_x];
+__inline float get_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y) {
+    if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
+        return 0.0f;
+    }
+    return buf[(pos_y * buf_x) + pos_x];
 }
 
-static float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v)
-{
-       int a;
-       int b;
-       int a_plus_1;
-       int b_plus_1;
-       float prop_u;
-       float prop_v;
-       float inv_prop_u;
-       float inv_prop_v;
-       if(u<0.0f || u>1.0f || v<0.0f || v>1.0f) {
-               return 0.0f;
-       }
-       u = u * (float)(buf_x) - 0.5f;
-       v = v * (float)(buf_y) - 0.5f;
-       a = (int)(u);
-       b = (int)(v);
-       prop_u = u - (float)(a);
-       prop_v = v - (float)(b);
-       inv_prop_u = 1.0f - prop_u;
-       inv_prop_v = 1.0f - prop_v;
-       a_plus_1 = MIN2((buf_x-1),a+1);
-       b_plus_1 = MIN2((buf_y-1),b+1);
-       return (buf[(b * buf_y) + a] * inv_prop_u + buf[(b*buf_y)+(a_plus_1)] * prop_u)*inv_prop_v+(buf[((b_plus_1) * buf_y)+a] * inv_prop_u + buf[((b_plus_1)*buf_y)+(a_plus_1)] * prop_u) * prop_v;
+__inline float get_pixel_intensity_bilinear(float *buf, int buf_x, int buf_y, float u, float v) {
+    int a;
+    int b;
+    int a_plus_1;
+    int b_plus_1;
+    float prop_u;
+    float prop_v;
+    float inv_prop_u;
+    float inv_prop_v;
+    if(u<0.0f || u>1.0f || v<0.0f || v>1.0f) {
+        return 0.0f;
+    }
+    u = u * (float)(buf_x) - 0.5f;
+    v = v * (float)(buf_y) - 0.5f;
+    a = (int)(u);
+    b = (int)(v);
+    prop_u = u - (float)(a);
+    prop_v = v - (float)(b);
+    inv_prop_u = 1.0f - prop_u;
+    inv_prop_v = 1.0f - prop_v;
+    a_plus_1 = MIN2((buf_x-1),a+1);
+    b_plus_1 = MIN2((buf_y-1),b+1);
+    return (buf[(b * buf_x) + a] * inv_prop_u + buf[(b*buf_x)+(a_plus_1)] * prop_u)*inv_prop_v+(buf[((b_plus_1) * buf_x)+a] * inv_prop_u + buf[((b_plus_1)*buf_x)+(a_plus_1)] * prop_u) * prop_v;
 
 }
 
-static void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity)
-{
-       if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
-               return;
-       }
-       buf[(pos_y * buf_y) + buf_x] = intensity;
+__inline void set_pixel_intensity(float *buf, int buf_x, int buf_y, int pos_x, int pos_y, float intensity) {
+    if(pos_x < 0 || pos_x >= buf_x || pos_y < 0 || pos_y >= buf_y) {
+        return;
+    }
+    buf[(pos_y * buf_x) + pos_x] = intensity;
 }
 #endif
 
-int PLX_antialias_buffer(float *buf, int buf_x, int buf_y)
-{
+int PLX_antialias_buffer(float *buf, int buf_x, int buf_y) {
 #ifdef __PLX__FAKE_AA__
 #ifdef __PLX_GREY_AA__
-       int i=0;
-       int sz = buf_x * buf_y;
-       for(i=0; i<sz; i++) {
-               buf[i] *= 0.5f;
-       }
+    int i=0;
+    int sz = buf_x * buf_y;
+    for(i=0; i<sz; i++) {
+        buf[i] *= 0.5f;
+    }
 #endif
-       (void)buf_x;
-       (void)buf_y;
-       (void)buf;
-       return 1;
+    (void)buf_x;
+    (void)buf_y;
+    (void)buf;
+    return 1;
 #else
-       /*XXX - TODO: THIS IS NOT FINAL CODE - IT DOES NOT WORK - DO NOT ENABLE IT */
-       const float p0 = 1.0f;
-       const float p1 = 1.0f;
-       const float p2 = 1.0f;
-       const float p3 = 1.0f;
-       const float p4 = 1.0f;
-       const float p5 = 1.5f;
-       const float p6 = 2.0f;
-       const float p7 = 2.0f;
-       const float p8 = 2.0f;
-       const float p9 = 2.0f;
-       const float p10 = 4.0f;
-       const float p11 = 8.0f;
-
-       const float edge_threshold = 0.063f;
-       const float edge_threshold_min = 0.0312f;
-       const float quality_subpix = 1.0f;
-//     int px_x;
-//     int px_y;
-
-       float posM_x,posM_y;
-       float posB_x,posB_y;
-       float posN_x,posN_y;
-       float posP_x,posP_y;
-       float offNP_x,offNP_y;
-       float lumaM;
-       float lumaS;
-       float lumaE;
-       float lumaN;
-       float lumaW;
-       float lumaNW;
-       float lumaSE;
-       float lumaNE;
-       float lumaSW;
-       float lumaNS;
-       float lumaWE;
-       float lumaNESE;
-       float lumaNWNE;
-       float lumaNWSW;
-       float lumaSWSE;
-       float lumaNN;
-       float lumaSS;
-       float lumaEndN;
-       float lumaEndP;
-       float lumaMM;
-       float lumaMLTZero;
-       float subpixNWSWNESE;
-       float subpixRcpRange;
-       float subpixNSWE;
-       float maxSM;
-       float minSM;
-       float maxESM;
-       float minESM;
-       float maxWN;
-       float minWN;
-       float rangeMax;
-       float rangeMin;
-       float rangeMaxScaled;
-       float range;
-       float rangeMaxClamped;
-       float edgeHorz;
-       float edgeVert;
-       float edgeHorz1;
-       float edgeVert1;
-       float edgeHorz2;
-       float edgeVert2;
-       float edgeHorz3;
-       float edgeVert3;
-       float edgeHorz4;
-       float edgeVert4;
-       float lengthSign;
-       float subpixA;
-       float subpixB;
-       float subpixC;
-       float subpixD;
-       float subpixE;
-       float subpixF;
-       float subpixG;
-       float subpixH;
-       float gradientN;
-       float gradientS;
-       float gradient;
-       float gradientScaled;
-       float dstN;
-       float dstP;
-       float dst;
-       float spanLength;
-       float spanLengthRcp;
-       float pixelOffset;
-       float pixelOffsetGood;
-       float pixelOffsetSubpix;
-       int directionN;
-       int goodSpan;
-       int goodSpanN;
-       int goodSpanP;
-       int horzSpan;
-       int earlyExit;
-       int pairN;
-       int doneN;
-       int doneP;
-       int doneNP;
-       int curr_x=0;
-       int curr_y=0;
-       for(curr_y=0; curr_y < buf_y; curr_y++) {
-               for(curr_x=0; curr_x < buf_x; curr_x++) {
-                       posM_x = ((float)(curr_x) + 0.5f) * (1.0f/(float)(buf_x));
-                       posM_y = ((float)(curr_y) + 0.5f) * (1.0f/(float)(buf_y));
-
-                       lumaM = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y);
-                       lumaS = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y - 1);
-                       lumaE = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y);
-                       lumaN = get_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y + 1);
-                       lumaW = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y);
-
-                       maxSM = MAX2(lumaS, lumaM);
-                       minSM = MIN2(lumaS, lumaM);
-                       maxESM = MAX2(lumaE, maxSM);
-                       minESM = MIN2(lumaE, minSM);
-                       maxWN = MAX2(lumaN, lumaW);
-                       minWN = MIN2(lumaN, lumaW);
-                       rangeMax = MAX2(maxWN, maxESM);
-                       rangeMin = MIN2(minWN, minESM);
-                       rangeMaxScaled = rangeMax * edge_threshold;
-                       range = rangeMax - rangeMin;
-                       rangeMaxClamped = MAX2(edge_threshold_min, rangeMaxScaled);
-
-                       earlyExit = range < rangeMaxClamped ? 1:0;
-                       if(earlyExit) {
-                               set_pixel_intensity(buf, buf_x, buf_y, curr_x, curr_y, lumaM);
-                       }
-
-                       lumaNW = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y - 1);
-                       lumaSE = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y + 1);
-                       lumaNE = get_pixel_intensity(buf, buf_x, buf_y, curr_x + 1, curr_y + 1);
-                       lumaSW = get_pixel_intensity(buf, buf_x, buf_y, curr_x - 1, curr_y - 1);
-
-                       lumaNS = lumaN + lumaS;
-                       lumaWE = lumaW + lumaE;
-                       subpixRcpRange = 1.0f/range;
-                       subpixNSWE = lumaNS + lumaWE;
-                       edgeHorz1 = (-2.0f * lumaM) + lumaNS;
-                       edgeVert1 = (-2.0f * lumaM) + lumaWE;
-
-                       lumaNESE = lumaNE + lumaSE;
-                       lumaNWNE = lumaNW + lumaNE;
-                       edgeHorz2 = (-2.0f * lumaE) + lumaNESE;
-                       edgeVert2 = (-2.0f * lumaN) + lumaNWNE;
-
-                       lumaNWSW = lumaNW + lumaSW;
-                       lumaSWSE = lumaSW + lumaSE;
-                       edgeHorz4 = (ABS(edgeHorz1) * 2.0f) + ABS(edgeHorz2);
-                       edgeVert4 = (ABS(edgeVert1) * 2.0f) + ABS(edgeVert2);
-                       edgeHorz3 = (-2.0f * lumaW) + lumaNWSW;
-                       edgeVert3 = (-2.0f * lumaS) + lumaSWSE;
-                       edgeHorz = ABS(edgeHorz3) + edgeHorz4;
-                       edgeVert = ABS(edgeVert3) + edgeVert4;
-
-                       subpixNWSWNESE = lumaNWSW + lumaNESE;
-                       lengthSign = 1.0f / (float)(buf_x);
-                       horzSpan = edgeHorz >= edgeVert ? 1:0;
-                       subpixA = subpixNSWE * 2.0f + subpixNWSWNESE;
-
-                       if(!horzSpan) {
-                               lumaN = lumaW;
-                               lumaS = lumaE;
-                       }
-                       else {
-                               lengthSign = 1.0f / (float)(buf_y);
-                       }
-                       subpixB = (subpixA * (1.0f/12.0f)) - lumaM;
-
-                       gradientN = lumaN - lumaM;
-                       gradientS = lumaS - lumaM;
-                       lumaNN = lumaN + lumaM;
-                       lumaSS = lumaS + lumaM;
-                       pairN = (ABS(gradientN)) >= (ABS(gradientS)) ? 1:0;
-                       gradient = MAX2(ABS(gradientN), ABS(gradientS));
-                       if(pairN) {
-                               lengthSign = -lengthSign;
-                       }
-                       subpixC = MAX2(MIN2(ABS(subpixB) * subpixRcpRange,1.0f),0.0f);
-
-                       posB_x = posM_x;
-                       posB_y = posM_y;
-                       offNP_x = (!horzSpan) ? 0.0f:(1.0f / (float)(buf_x));
-                       offNP_y = (horzSpan) ? 0.0f:(1.0f / (float)(buf_y));
-                       if(!horzSpan) {
-                               posB_x += lengthSign * 0.5f;
-                       }
-                       else {
-                               posB_y += lengthSign * 0.5f;
-                       }
-
-                       posN_x = posB_x - offNP_x * p0;
-                       posN_y = posB_y - offNP_y * p0;
-                       posP_x = posB_x + offNP_x * p0;
-                       posP_y = posB_y + offNP_y * p0;
-                       subpixD = ((-2.0f)*subpixC) + 3.0f;
-                       //may need bilinear filtered get_pixel_intensity() here...done
-                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y,posN_x,posN_y);
-                       subpixE = subpixC * subpixC;
-                       //may need bilinear filtered get_pixel_intensity() here...done
-                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x,posP_y);
-
-                       if(!pairN) {
-                               lumaNN = lumaSS;
-                       }
-                       gradientScaled = gradient * 1.0f/4.0f;
-                       lumaMM =lumaM - lumaNN * 0.5f;
-                       subpixF = subpixD * subpixE;
-                       lumaMLTZero = lumaMM < 0.0f ? 1:0;
-
-                       lumaEndN -= lumaNN * 0.5f;
-                       lumaEndP -= lumaNN * 0.5f;
-                       doneN = (ABS(lumaEndN)) >= gradientScaled ? 1:0;
-                       doneP = (ABS(lumaEndP)) >= gradientScaled ? 1:0;
-                       if(!doneN) {
-                               posN_x -= offNP_x * p1;
-                               posN_y -= offNP_y * p1;
-                       }
-                       doneNP = (!doneN) || (!doneP) ? 1:0;
-                       if(!doneP) {
-                               posP_x += offNP_x * p1;
-                               posP_y += offNP_y * p1;
-                       }
-
-                       if(doneNP) {
-                               if(!doneN) {
-                                       lumaEndN = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posN_x,posN_y);
-                               }
-                               if(!doneP) {
-                                       lumaEndP = get_pixel_intensity_bilinear(buf, buf_x, buf_y, posP_x, posP_y);
-                               }
-                               if(!doneN) {
-                                       lumaEndN&n