Merged changes in the trunk up to revision 36551.
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Mon, 9 May 2011 01:38:29 +0000 (01:38 +0000)
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>
Mon, 9 May 2011 01:38:29 +0000 (01:38 +0000)
Conflicts resolved:
source/creator/SConscript

304 files changed:
SConstruct
build_files/cmake/packaging.cmake
build_files/package_spec/debian/menu
build_files/package_spec/rpm/blender.spec.in [new file with mode: 0644]
build_files/scons/tools/btools.py
doc/doxygen/doxygen.source
doc/python_api/sphinx_doc_gen.py
extern/CMakeLists.txt
extern/SConscript
extern/bullet2/uninitialized_stack_vec.patch [deleted file]
intern/container/CMakeLists.txt
intern/container/CTR_HashedPtr.h [moved from source/kernel/gen_system/GEN_HashedPtr.h with 67% similarity]
intern/container/CTR_Map.h
intern/container/SConscript
intern/ghost/GHOST_C-api.h
intern/ghost/GHOST_ISystem.h
intern/ghost/intern/GHOST_C-api.cpp
intern/ghost/intern/GHOST_Debug.h
intern/ghost/intern/GHOST_SystemCarbon.h
intern/ghost/intern/GHOST_SystemCocoa.h
intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_SystemWin32.h
intern/ghost/intern/GHOST_SystemX11.cpp
intern/ghost/intern/GHOST_SystemX11.h
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.h
release/scripts/modules/bpy/path.py
release/scripts/modules/bpy/utils.py
release/scripts/modules/io_utils.py
release/scripts/startup/bl_operators/presets.py
release/scripts/startup/bl_operators/wm.py
release/scripts/startup/bl_ui/properties_data_modifier.py
release/scripts/startup/bl_ui/properties_game.py
release/scripts/startup/bl_ui/properties_material.py
release/scripts/startup/bl_ui/properties_physics_cloth.py
release/scripts/startup/bl_ui/properties_texture.py
release/scripts/startup/bl_ui/space_image.py
release/scripts/startup/bl_ui/space_text.py
release/scripts/startup/bl_ui/space_userpref.py
release/scripts/startup/bl_ui/space_userpref_keymap.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/CMakeLists.txt
source/SConscript
source/blender/blenfont/BLF_api.h
source/blender/blenfont/intern/blf.c
source/blender/blenkernel/BKE_blender.h
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_collision.h
source/blender/blenkernel/BKE_exotic.h [deleted file]
source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/BKE_text.h
source/blender/blenkernel/CMakeLists.txt
source/blender/blenkernel/SConscript
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/blender.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/context.c
source/blender/blenkernel/intern/exotic.c [deleted file]
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/implicit.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/seqeffects.c
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenkernel/intern/text.c
source/blender/blenkernel/intern/texture.c
source/blender/blenlib/BLI_dynlib.h [moved from source/blender/blenlib/PIL_dynlib.h with 72% similarity]
source/blender/blenlib/BLI_listbase.h
source/blender/blenlib/BLI_math_geom.h
source/blender/blenlib/BLI_path_util.h
source/blender/blenlib/BLI_winstuff.h
source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/intern/dynlib.c
source/blender/blenlib/intern/listbase.c
source/blender/blenlib/intern/math_geom.c
source/blender/blenlib/intern/path_util.c
source/blender/blenlib/intern/winstuff.c
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/animation/anim_filter.c
source/blender/editors/datafiles/startup.blend.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/gpencil/gpencil_paint.c
source/blender/editors/include/ED_uvedit.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_draw.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/editors/mesh/mesh_ops.c
source/blender/editors/object/object_constraint.c
source/blender/editors/object/object_intern.h
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_select.c
source/blender/editors/object/object_transform.c
source/blender/editors/render/render_internal.c
source/blender/editors/screen/screen_ops.c
source/blender/editors/screen/screendump.c
source/blender/editors/sculpt_paint/paint_image.c
source/blender/editors/sculpt_paint/paint_ops.c
source/blender/editors/sculpt_paint/paint_stroke.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_image/CMakeLists.txt
source/blender/editors/space_image/image_buttons.c
source/blender/editors/space_image/image_header.c [deleted file]
source/blender/editors/space_image/image_ops.c
source/blender/editors/space_image/space_image.c
source/blender/editors/space_node/drawnode.c
source/blender/editors/space_node/node_edit.c
source/blender/editors/space_node/node_header.c
source/blender/editors/space_node/node_intern.h
source/blender/editors/space_outliner/outliner.c
source/blender/editors/space_text/text_draw.c
source/blender/editors/space_text/text_ops.c
source/blender/editors/space_view3d/CMakeLists.txt
source/blender/editors/space_view3d/SConscript
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawobject.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_header.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/transform/transform_generics.c
source/blender/editors/transform/transform_input.c
source/blender/editors/util/crazyspace.c
source/blender/editors/uvedit/CMakeLists.txt
source/blender/editors/uvedit/uvedit_buttons.c [new file with mode: 0644]
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/intern/gpu_shader_material.glsl
source/blender/gpu/intern/gpu_shader_material.glsl.c
source/blender/imbuf/IMB_thumbs.h
source/blender/imbuf/intern/dds/BlockDXT.cpp
source/blender/imbuf/intern/dds/BlockDXT.h
source/blender/imbuf/intern/dds/Color.h
source/blender/imbuf/intern/dds/ColorBlock.cpp
source/blender/imbuf/intern/dds/ColorBlock.h
source/blender/imbuf/intern/dds/Common.h
source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
source/blender/imbuf/intern/dds/DirectDrawSurface.h
source/blender/imbuf/intern/dds/Image.cpp
source/blender/imbuf/intern/dds/Image.h
source/blender/imbuf/intern/dds/PixelFormat.h
source/blender/imbuf/intern/dds/Stream.cpp
source/blender/imbuf/intern/dds/Stream.h
source/blender/imbuf/intern/dds/dds_api.cpp
source/blender/imbuf/intern/dds/dds_api.h
source/blender/imbuf/intern/thumbs.c
source/blender/makesdna/DNA_cloth_types.h
source/blender/makesdna/DNA_modifier_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_access.c
source/blender/makesrna/intern/rna_armature.c
source/blender/makesrna/intern/rna_cloth.c
source/blender/makesrna/intern/rna_mesh_api.c
source/blender/makesrna/intern/rna_modifier.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_object.c
source/blender/makesrna/intern/rna_pose.c
source/blender/makesrna/intern/rna_render.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_sculpt_paint.c
source/blender/makesrna/intern/rna_space.c
source/blender/makesrna/intern/rna_ui_api.c
source/blender/makesrna/intern/rna_wm_api.c
source/blender/modifiers/CMakeLists.txt
source/blender/modifiers/MOD_modifiertypes.h
source/blender/modifiers/intern/MOD_displace.c
source/blender/modifiers/intern/MOD_multires.c
source/blender/modifiers/intern/MOD_util.c
source/blender/modifiers/intern/MOD_util.h
source/blender/modifiers/intern/MOD_warp.c [new file with mode: 0644]
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_rna_anim.c
source/blender/readblenfile/CMakeLists.txt
source/blender/readblenfile/SConscript
source/blender/readblenfile/stub/BLO_readblenfileSTUB.c
source/blender/render/CMakeLists.txt
source/blender/render/intern/source/rayshade.c
source/blender/render/intern/source/render_texture.c
source/blender/windowmanager/CMakeLists.txt
source/blender/windowmanager/SConscript
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_operators.c
source/blenderplayer/CMakeLists.txt
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/CMakeLists.txt
source/creator/SConscript
source/creator/creator.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/BlenderRoutines/BL_System.cpp [moved from source/kernel/gen_system/SYS_System.cpp with 60% similarity]
source/gameengine/BlenderRoutines/BL_System.h [moved from source/kernel/gen_system/SYS_System.h with 75% similarity]
source/gameengine/BlenderRoutines/CMakeLists.txt
source/gameengine/BlenderRoutines/SConscript
source/gameengine/Converter/BL_ActionActuator.h
source/gameengine/Converter/BL_ArmatureActuator.cpp
source/gameengine/Converter/BL_ArmatureActuator.h
source/gameengine/Converter/BL_ArmatureChannel.h
source/gameengine/Converter/BL_ArmatureConstraint.cpp
source/gameengine/Converter/BL_ArmatureConstraint.h
source/gameengine/Converter/BL_ArmatureObject.cpp
source/gameengine/Converter/BL_ArmatureObject.h
source/gameengine/Converter/BL_BlenderDataConversion.cpp
source/gameengine/Converter/BL_BlenderDataConversion.h
source/gameengine/Converter/BL_DeformableGameObject.h
source/gameengine/Converter/BL_MeshDeformer.cpp
source/gameengine/Converter/BL_MeshDeformer.h
source/gameengine/Converter/BL_ModifierDeformer.cpp
source/gameengine/Converter/BL_ShapeActionActuator.h
source/gameengine/Converter/BL_ShapeDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.cpp
source/gameengine/Converter/BL_SkinDeformer.h
source/gameengine/Converter/CMakeLists.txt
source/gameengine/Converter/KX_BlenderSceneConverter.cpp
source/gameengine/Converter/KX_BlenderSceneConverter.h
source/gameengine/Converter/KX_SoftBodyDeformer.cpp
source/gameengine/Converter/KX_SoftBodyDeformer.h
source/gameengine/Converter/SConscript
source/gameengine/Expressions/CMakeLists.txt
source/gameengine/Expressions/SConscript
source/gameengine/GameLogic/CMakeLists.txt
source/gameengine/GameLogic/SCA_ILogicBrick.cpp
source/gameengine/GameLogic/SCA_ILogicBrick.h
source/gameengine/GameLogic/SCA_LogicManager.h
source/gameengine/GameLogic/SCA_PropertyActuator.cpp
source/gameengine/GameLogic/SCA_PropertyActuator.h
source/gameengine/GameLogic/SConscript
source/gameengine/GamePlayer/common/CMakeLists.txt
source/gameengine/GamePlayer/common/GPC_Engine.cpp
source/gameengine/GamePlayer/common/SConscript
source/gameengine/GamePlayer/ghost/CMakeLists.txt
source/gameengine/GamePlayer/ghost/GPG_Application.cpp
source/gameengine/GamePlayer/ghost/GPG_Application.h
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/GamePlayer/ghost/SConscript
source/gameengine/Ketsji/CMakeLists.txt
source/gameengine/Ketsji/KXNetwork/CMakeLists.txt
source/gameengine/Ketsji/KXNetwork/SConscript
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_CameraActuator.h
source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
source/gameengine/Ketsji/KX_GameObject.cpp
source/gameengine/Ketsji/KX_GameObject.h
source/gameengine/Ketsji/KX_ObjectActuator.cpp
source/gameengine/Ketsji/KX_ObjectActuator.h
source/gameengine/Ketsji/KX_ParentActuator.cpp
source/gameengine/Ketsji/KX_ParentActuator.h
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.cpp
source/gameengine/Ketsji/KX_SCA_AddObjectActuator.h
source/gameengine/Ketsji/KX_Scene.cpp
source/gameengine/Ketsji/KX_Scene.h
source/gameengine/Ketsji/KX_SceneActuator.cpp
source/gameengine/Ketsji/KX_SceneActuator.h
source/gameengine/Ketsji/KX_TrackToActuator.cpp
source/gameengine/Ketsji/KX_TrackToActuator.h
source/gameengine/Ketsji/SConscript
source/gameengine/Network/CMakeLists.txt
source/gameengine/Network/LoopBackNetwork/CMakeLists.txt
source/gameengine/Network/LoopBackNetwork/SConscript
source/gameengine/Network/NG_NetworkScene.h
source/gameengine/Network/SConscript
source/gameengine/Physics/Bullet/CMakeLists.txt
source/gameengine/Physics/Bullet/SConscript
source/gameengine/Rasterizer/CMakeLists.txt
source/gameengine/Rasterizer/RAS_BucketManager.cpp
source/gameengine/Rasterizer/RAS_BucketManager.h
source/gameengine/Rasterizer/RAS_Deformer.h
source/gameengine/Rasterizer/RAS_MaterialBucket.h
source/gameengine/Rasterizer/RAS_MeshObject.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/CMakeLists.txt
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/SConscript
source/gameengine/Rasterizer/SConscript
source/gameengine/VideoTexture/CMakeLists.txt
source/gameengine/VideoTexture/SConscript
source/kernel/CMakeLists.txt [deleted file]
source/kernel/SConscript [deleted file]
source/kernel/gen_messaging/GEN_messaging.h [deleted file]
source/kernel/gen_messaging/intern/messaging.c [deleted file]
source/kernel/gen_system/GEN_HashedPtr.cpp [deleted file]
source/kernel/gen_system/GEN_Map.h [deleted file]
source/kernel/gen_system/SYS_SingletonSystem.cpp [deleted file]
source/kernel/gen_system/SYS_SingletonSystem.h [deleted file]

index 954422e0b3da7795d2bd35fa7da715a93172a403..e928970f6b84da541facf6d2801ca789b68d9e52 100644 (file)
@@ -568,9 +568,10 @@ pluglist.append('source/blender/blenpluginapi/plugin.DEF')
 plugtargetlist.append(os.path.join(env['BF_INSTALLDIR'], VERSION, 'plugins', 'include', 'plugin.def'))
 
 plugininstall = []
-for targetdir,srcfile in zip(plugtargetlist, pluglist):
-    td, tf = os.path.split(targetdir)
-    plugininstall.append(env.Install(dir=td, source=srcfile))
+# plugins in blender 2.5 don't work at the moment.
+#for targetdir,srcfile in zip(plugtargetlist, pluglist):
+#    td, tf = os.path.split(targetdir)
+#    plugininstall.append(env.Install(dir=td, source=srcfile))
 
 textlist = []
 texttargetlist = []
index ee07857db260552f56a83f3bb26d7bcf251d6b97..07c5add52b007f69daecd8cda45a20a00ff0cc1f 100644 (file)
@@ -31,17 +31,20 @@ set(BUILD_REV ${MY_WC_REVISION})
 
 
 # Force Package Name
-set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${BLENDER_VERSION}-r${BUILD_REV}-${CPACK_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR})
+set(CPACK_PACKAGE_FILE_NAME ${PROJECT_NAME}-${BLENDER_VERSION}-r${BUILD_REV}-${CMAKE_SYSTEM_PROCESSOR})
 
 if(CMAKE_SYSTEM_NAME MATCHES "Linux")
        # RPM packages
        include(build_files/cmake/RpmBuild.cmake)
        if(RPMBUILD_FOUND AND NOT WIN32)
                set(CPACK_GENERATOR "RPM")
-               set(CPACK_SET_DESTDIR TRUE)
+               set(CPACK_RPM_PACKAGE_RELEASE "r${BUILD_REV}")
+               set(CPACK_SET_DESTDIR "true")
                set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_DESCRIPTION}")
+               set(CPACK_PACKAGE_RELOCATABLE "false")
                set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
                set(CPACK_RPM_PACKAGE_GROUP "Amusements/Graphics")
+               set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_SOURCE_DIR}/build_files/package_spec/rpm/blender.spec.in")
        endif()
 endif()
 
index 1124c723b3c26cf32d037a6037bebe3730d15f2b..d69c7354f3c3cee1f24144252950655ebdba495b 100644 (file)
@@ -1,4 +1,4 @@
 ?package(blender-snapshot):needs="X11" section="Applications/Graphics"\
   longtitle="Blender 3D modeler / renderer"\
-  icon="/usr/share/pixmaps/blender.svg"\
+  icon="/usr/share/icons/hicolor/scalable/apps/blender.svg"\
   title="blender" command="/usr/bin/blender"
diff --git a/build_files/package_spec/rpm/blender.spec.in b/build_files/package_spec/rpm/blender.spec.in
new file mode 100644 (file)
index 0000000..32c9ef9
--- /dev/null
@@ -0,0 +1,69 @@
+# -*- rpm-spec -*-
+%global __python %{__python3}
+
+BuildRoot:      @CPACK_RPM_DIRECTORY@/@CPACK_PACKAGE_FILE_NAME@@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH@
+Summary:        @CPACK_RPM_PACKAGE_SUMMARY@
+Name:           @CPACK_RPM_PACKAGE_NAME@
+Version:        @CPACK_RPM_PACKAGE_VERSION@
+Release:        @CPACK_RPM_PACKAGE_RELEASE@
+License:        @CPACK_RPM_PACKAGE_LICENSE@
+Group:          @CPACK_RPM_PACKAGE_GROUP@
+Vendor:         @CPACK_RPM_PACKAGE_VENDOR@
+
+%define _rpmdir @CPACK_RPM_DIRECTORY@
+%define _rpmfilename @CPACK_RPM_FILE_NAME@
+%define _unpackaged_files_terminate_build 0
+%define _topdir @CPACK_RPM_DIRECTORY@
+
+%description
+Blender is an integrated 3d suite for modelling, animation, rendering,
+post-production, interactive creation and playback (games). Blender has its
+own particular user interface, which is implemented entirely in OpenGL and
+designed with speed in mind. Python bindings are available for scripting;
+import/export features for popular file formats like 3D Studio and Wavefront
+Obj are implemented as scripts by the community. Stills, animations, models
+for games or other third party engines and interactive content in the form of
+a standalone binary and/or a web plug-in are common products of Blender use.
+
+# This is a shortcutted spec file generated by CMake RPM generator
+# we skip _install step because CPack does that for us.
+# We do only save CPack installed tree in _prepr
+# and then restore it in build.
+%prep
+mv ${RPM_BUILD_ROOT} "@CPACK_TOPLEVEL_DIRECTORY@/tmpBBroot"
+
+%install
+if [ -e ${RPM_BUILD_ROOT} ];
+then
+  rm -rf ${RPM_BUILD_ROOT}
+fi
+mv "@CPACK_TOPLEVEL_DIRECTORY@/tmpBBroot" ${RPM_BUILD_ROOT}
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%post
+touch --no-create %{_datadir}/icons/hicolor
+if [ -x %{_bindir}/gtk-update-icon-cache ]; then
+  %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor
+fi 
+%{_bindir}/update-desktop-database %{_datadir}/applications || :
+
+%postun
+%{_bindir}/update-desktop-database %{_datadir}/applications
+touch --no-create %{_datadir}/icons/hicolor
+if [ -x %{_bindir}/gtk-update-icon-cache ]; then
+  %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor
+fi || :
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/%{name}
+%{_datadir}/%{name}/@CPACK_PACKAGE_VERSION_MAJOR@.@CPACK_PACKAGE_VERSION_MINOR@
+%{_datadir}/icons/hicolor/*/apps/%{name}.*
+%{_datadir}/applications/%{name}.desktop
+%{_datadir}/doc/blender
+%{_mandir}/man1/blender.*
+
+%changelog
+@CPACK_RPM_SPEC_CHANGELOG@
index a646b9084c2879b1ad5519b21f7373afa935b165..fcc782bd824245e4606efda1c1da50f6e32df348 100644 (file)
@@ -99,7 +99,7 @@ def validate_arguments(args, bc):
             'WITH_BF_INTERNATIONAL',
             'BF_GETTEXT', 'BF_GETTEXT_INC', 'BF_GETTEXT_LIB', 'WITH_BF_GETTEXT_STATIC', 'BF_GETTEXT_LIB_STATIC', 'BF_GETTEXT_LIBPATH',
             'WITH_BF_ICONV', 'BF_ICONV', 'BF_ICONV_INC', 'BF_ICONV_LIB', 'BF_ICONV_LIBPATH',
-            'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
+            'WITH_BF_GAMEENGINE', 'WITH_BF_BULLET', 'WITH_BF_ELTOPO', 'BF_BULLET', 'BF_BULLET_INC', 'BF_BULLET_LIB',
             'BF_WINTAB', 'BF_WINTAB_INC',
             'WITH_BF_FREETYPE', 'BF_FREETYPE', 'BF_FREETYPE_INC', 'BF_FREETYPE_LIB', 'BF_FREETYPE_LIBPATH', 'BF_FREETYPE_LIB_STATIC', 'WITH_BF_FREETYPE_STATIC',
             'WITH_BF_QUICKTIME', 'BF_QUICKTIME', 'BF_QUICKTIME_INC', 'BF_QUICKTIME_LIB', 'BF_QUICKTIME_LIBPATH',
@@ -365,6 +365,8 @@ def read_opts(env, cfg, args):
         (BoolVariable('WITH_BF_GAMEENGINE', 'Build with gameengine' , False)),
 
         (BoolVariable('WITH_BF_BULLET', 'Use Bullet if true', True)),
+        (BoolVariable('WITH_BF_ELTOPO', 'Use Eltopo collision library if true', False)),
+        
         ('BF_BULLET', 'Bullet base dir', ''),
         ('BF_BULLET_INC', 'Bullet include path', ''),
         ('BF_BULLET_LIB', 'Bullet library', ''),
index 9cd86e23e591c52ef393df3fb876b0dc659adf06..ccdf3448f180c8c7f60eeb2004c42366dcd13f11 100644 (file)
 
 /* ================================ */
 
-/** \defgroup kernel kernel */
-
-/** \defgroup genmess gen_messaging
- *  \ingroup kernel
- */
-
-/** \defgroup gensys gen_system
- *  \ingroup kernel
- */
-
-/* ================================ */
-
 /** \defgroup undoc Undocumented
  *  \brief Modules and libraries that are still undocumented, or lacking proper integration into the doxygen system, are marked in this group. */
index 9930c7b02c139f41b128225cfad1b63f0691ddf5..6aafd3af8c4f4197bc2ce3fb03217e7c5b95abcc 100644 (file)
@@ -818,7 +818,9 @@ def pyrna2sphinx(BASEPATH):
 
     # operators
     def write_ops():
-        API_BASEURL = "https://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts"
+        API_BASEURL = "http://svn.blender.org/svnroot/bf-blender/trunk/blender/release/scripts"
+        API_BASEURL_ADDON = "http://svn.blender.org/svnroot/bf-extensions/trunk/py/scripts"
+        API_BASEURL_ADDON_CONTRIB = "http://svn.blender.org/svnroot/bf-extensions/contrib/py/scripts"
 
         op_modules = {}
         for op in ops.values():
@@ -857,7 +859,14 @@ def pyrna2sphinx(BASEPATH):
 
                 location = op.get_location()
                 if location != (None, None):
-                    fw("   :file: `%s <%s/%s>`_:%d\n\n" % (location[0], API_BASEURL, location[0], location[1]))
+                    if location[0].startswith("addons_contrib" + os.sep):
+                        url_base = API_BASEURL_ADDON_CONTRIB
+                    elif location[0].startswith("addons" + os.sep):
+                        url_base = API_BASEURL_ADDON
+                    else:
+                        url_base = API_BASEURL
+
+                    fw("   :file: `%s <%s/%s>`_:%d\n\n" % (location[0], url_base, location[0], location[1]))
 
             file.close()
 
index d74c6683f2c7dcdd4c95242a96b3efb8e4e10f6e..3990d132757f62e7696de42aa025faa8ae940319 100644 (file)
@@ -31,6 +31,10 @@ if(WITH_BULLET)
        add_subdirectory(bullet2)
 endif()
 
+if(WITH_MOD_CLOTH_ELTOPO)
+       add_subdirectory(eltopo)
+endif()
+
 if(WITH_BINRELOC)
        add_subdirectory(binreloc)
 endif()
index bd73d71f1238f4d57942dc18bb9b0daaa509448c..061bd1ba6a38bda04eab51704546efed9cec2a9b 100644 (file)
@@ -4,6 +4,9 @@ Import('env')
 
 SConscript(['glew/SConscript'])
 
+if env['WITH_BF_ELTOPO']:
+    SConscript(['eltopo/SConscript'])
+
 if env['WITH_BF_BULLET']:
     SConscript(['bullet2/src/SConscript'])
 
diff --git a/extern/bullet2/uninitialized_stack_vec.patch b/extern/bullet2/uninitialized_stack_vec.patch
deleted file mode 100644 (file)
index 96833b7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Index: src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
-===================================================================
---- src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp       (revision 34336)
-+++ src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp       (working copy)
-@@ -61,10 +61,12 @@
-       scaledAabbMin[0] = m_localScaling.getX() >= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0];
-       scaledAabbMin[1] = m_localScaling.getY() >= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1];
-       scaledAabbMin[2] = m_localScaling.getZ() >= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2];
-+      scaledAabbMin[3] = 0.0; /* otherwise un-initialized stack memory: uninitialized_stack_vec.patch, blender patch */
-       
-       scaledAabbMax[0] = m_localScaling.getX() <= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0];
-       scaledAabbMax[1] = m_localScaling.getY() <= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1];
-       scaledAabbMax[2] = m_localScaling.getZ() <= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2];
-+      scaledAabbMax[3] = 0.0; /* otherwise un-initialized stack memory: uninitialized_stack_vec.patch, blender patch */
-       
-       
-       m_bvhTriMeshShape->processAllTriangles(&scaledCallback,scaledAabbMin,scaledAabbMax);
index 7f15854e538e41874f490e628940c3704945a214..7e83acf68cec4f2cbb3990ededdd82c40cebfb2e 100644 (file)
 
 set(INC
        .
+       ../guardedalloc
 )
 
 set(SRC
        intern/CTR_List.cpp
 
+       CTR_HashedPtr.h
        CTR_List.h
        CTR_Map.h
        CTR_TaggedIndex.h
similarity index 67%
rename from source/kernel/gen_system/GEN_HashedPtr.h
rename to intern/container/CTR_HashedPtr.h
index 86a7ceb9ae77937e359aadfbff469ddde3901571..0291535d7185c6928ab4533fa3fb5cd932a2a96a 100644 (file)
  *
  */
 
-/** \file kernel/gen_system/GEN_HashedPtr.h
- *  \ingroup gensys
+/** \file container/CTR_HashedPtr.h
+ *  \ingroup ctr
  */
 
-#ifndef __GEN_HASHEDPTR
-#define __GEN_HASHEDPTR
+#ifndef CTR_HASHEDPTR_H
+#define CTR_HASHEDPTR_H
 
-unsigned int GEN_Hash(void * inDWord);
+#include <stdlib.h>
 
-class GEN_HashedPtr
+inline unsigned int CTR_Hash(void *inDWord)
+{
+       size_t key = (size_t)inDWord;
+       return (unsigned int)(key ^ (key>>4));
+}
+
+class CTR_HashedPtr
 {
        void* m_valptr;
 public:
-       GEN_HashedPtr(void* val) : m_valptr(val) {};
-       unsigned int hash() const { return GEN_Hash(m_valptr);};
-       inline friend bool operator ==(const GEN_HashedPtr & rhs, const GEN_HashedPtr & lhs) { return rhs.m_valptr == lhs.m_valptr;};
+       CTR_HashedPtr(void* val) : m_valptr(val) {};
+       unsigned int hash() const { return CTR_Hash(m_valptr);};
+       inline friend bool operator ==(const CTR_HashedPtr & rhs, const CTR_HashedPtr & lhs) { return rhs.m_valptr == lhs.m_valptr;};
        void *getValue() const { return m_valptr; }
 };
 
-#endif //__GEN_HASHEDPTR
+#endif //CTR_HASHEDPTR_H
 
index cbd67fdeaca5bd30cbd1970a996209ff34fc4336..1991ec19e3a6e37b824d0cdb1235c510bc828031 100644 (file)
@@ -55,6 +55,19 @@ public:
             m_buckets[i] = 0;
         }
     }
+
+       CTR_Map(const CTR_Map& map)
+       {
+               m_num_buckets = map.m_num_buckets;
+               m_buckets = new Entry *[m_num_buckets];
+
+               for (int i = 0; i < m_num_buckets; ++i) {
+                       m_buckets[i] = 0;
+
+                       for(Entry *entry = map.m_buckets[i]; entry; entry=entry->m_next)
+                               insert(entry->m_key, entry->m_value);
+               }
+       }
     
     int size() { 
         int count=0;
@@ -87,6 +100,24 @@ public:
         }
         return 0;
     }
+
+    Key* getKey(int index) {
+        int count=0;
+        for (int i=0;i<m_num_buckets;i++)
+        {
+            Entry* bucket = m_buckets[i];
+            while(bucket)
+            {
+                if (count==index)
+                {
+                    return &bucket->m_key;
+                }
+                bucket = bucket->m_next;
+                count++;
+            }
+        }
+        return 0;
+    }
     
     void clear() {
         for (int i = 0; i < m_num_buckets; ++i) {
index 2d93e90b555df5aee467d741fd90366b16e0d940..8edf86d7d4acc1e8f68c8bea3cd09c7165168763 100644 (file)
@@ -2,6 +2,6 @@
 Import ('env')
 
 sources = env.Glob('intern/*.cpp')
-incs = '.'
+incs = '. #intern/guardedalloc'
 
 env.BlenderLib ('bf_intern_ctr', sources, Split(incs) , [], libtype='intern', priority = 10 )
index be8dc138797d1f9b8a028ccacc47ccb9e74cc140..75837239c4ac75fb30152750598a066aa98f4024 100644 (file)
@@ -845,6 +845,18 @@ extern GHOST_TUns8* GHOST_getClipboard(int selection);
 extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection);
 
 
+
+/**
+ * Toggles console
+ * @action     0 - Hides
+ *                     1 - Shows
+ *                     2 - Toggles
+ *                     3 - Hides if it runs not from  command line
+ *                     * - Does nothing
+ * @return current status (1 -visible, 0 - hidden)
+ */
+extern int GHOST_toggleConsole(int action);
+
 #ifdef __cplusplus
 }
 #endif
index 38c732153d79c201aeb97f770023f3ef52bd23a2..69e10070be57a87c87fbcc8848b0ae296b9eb465 100644 (file)
@@ -355,6 +355,16 @@ public:
         */
        virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool& isDown) const = 0;
 
+       /**
+        * Toggles console
+        * @action      0 - Hides
+        *                      1 - Shows
+        *                      2 - Toggles
+        *                      3 - Hides if it runs not from  command line
+        *                      * - Does nothing
+        * @return current status (1 -visible, 0 - hidden)
+        */
+       virtual int toggleConsole(int action) = 0;
        
        /***************************************************************************************
         ** Access to clipboard.
index a1e1bafa82fe05d84bd9b02d0fbdc5380ba54012..7ba8d7db411c3d281a1bb9dce7ea47c8804d1165 100644 (file)
@@ -877,3 +877,9 @@ void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection)
        GHOST_ISystem* system = GHOST_ISystem::getSystem();
        system->putClipboard(buffer, selection);
 }
+
+int GHOST_toggleConsole(int action)
+{
+       GHOST_ISystem* system = GHOST_ISystem::getSystem();
+       return system->toggleConsole(action);
+}
index 602f52a6435c3998c3da9a8bbfdfb1b3212713b1..e77f3b9c46106681678e61b18ff61fef019647b1 100644 (file)
 
 #ifdef GHOST_DEBUG
        #define GHOST_PRINT(x) { std::cout << x; }
-       //#define GHOST_PRINTF(x) { printf(x); }
+       #define GHOST_PRINTF(x, ...) { printf(x, __VA_ARGS__); }
 #else  // GHOST_DEBUG
        #define GHOST_PRINT(x)
-       //#define GHOST_PRINTF(x)
+       #define GHOST_PRINTF(x, ...)
 #endif // GHOST_DEBUG
 
 
index ae15afdbcdeabf82a009f504212732e42361b2e5..b0cf622f70932d5d37ce62edf498f5a32f2519a1 100644 (file)
@@ -191,6 +191,11 @@ public:
         */
        virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
 
+       /**
+        * @see GHOST_ISystem
+        */
+       int toggleConsole(int action) { return 0; }
+
 protected:
        /**
         * Initializes the system.
index dbe879dc6291dae6548b3b30c64b6aed2db49e80..e7a8178a38259a2910a44e9b0901c3a3df280232 100644 (file)
@@ -227,6 +227,11 @@ public:
      * @return Indication whether the event was handled. 
      */
     GHOST_TSuccess handleApplicationBecomeActiveEvent();
+
+       /**
+        * @see GHOST_ISystem
+        */
+       int toggleConsole(int action) { return 0; }
        
        
 protected:
index dc16711b532979355ce7b4d282313b0364e50af1..455a166ece0926f72f962b7df25d43faefe65799 100644 (file)
 
 #include <iostream>
 
+#ifdef FREE_WINDOWS
+#  define _WIN32_WINNT 0x0500 /* GetConsoleWindow() for MinGW */
+#endif
+
 #include "GHOST_SystemWin32.h"
 #include "GHOST_EventDragnDrop.h"
 
@@ -174,6 +178,8 @@ GHOST_SystemWin32::GHOST_SystemWin32()
        GHOST_ASSERT(m_displayManager, "GHOST_SystemWin32::GHOST_SystemWin32(): m_displayManager==0\n");
        m_displayManager->initialize();
 
+       m_consoleStatus = 1;
+
        // Check if current keyboard layout uses AltGr and save keylayout ID for
        // specialized handling if keys like VK_OEM_*. I.e. french keylayout
        // generates VK_OEM_8 for their exclamation key (key left of right shift)
@@ -186,6 +192,7 @@ GHOST_SystemWin32::~GHOST_SystemWin32()
 {
        // Shutdown COM
        OleUninitialize();
+       toggleConsole(1);
 }
 
 
@@ -231,7 +238,7 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
        bool stereoVisual, const GHOST_TUns16 numOfAASamples, const GHOST_TEmbedderWindowID parentWindow )
 {
        GHOST_Window* window = 0;
-       window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples);
+       window = new GHOST_WindowWin32 (this, title, left, top, width, height, state, type, stereoVisual, numOfAASamples, parentWindow);
        if (window) {
                if (window->getValid()) {
                        // Store the pointer to the window
@@ -240,6 +247,14 @@ GHOST_IWindow* GHOST_SystemWin32::createWindow(
 //                     }
                }
                else {
+
+                       // Invalid parent window hwnd
+                       if (((GHOST_WindowWin32*)window)->getNextWindow() == NULL) {
+                               delete window;
+                               window = 0;
+                               return window;
+                       }
+
                        // An invalid window could be one that was used to test for AA
                        window = ((GHOST_WindowWin32*)window)->getNextWindow();
                        
@@ -289,7 +304,6 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent)
 
                // Process all the events waiting for us
                while (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0) {
-                       ::TranslateMessage(&msg);
                        ::DispatchMessage(&msg);
                        anyProcessed = true;
                }
@@ -804,6 +818,11 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                // Keyboard events, processed
                                ////////////////////////////////////////////////////////////////////////
                                case WM_INPUT:
+                                       // check WM_INPUT from input sink when ghost window is not in the foreground
+                                       if (wParam == RIM_INPUTSINK) {
+                                               if (GetFocus() != hwnd) // WM_INPUT message not for this window
+                                                       return 0;
+                                       } //else wPAram == RIM_INPUT
                                        event = processKeyEvent(window, wParam, lParam);
                                        if (!event) {
                                                GHOST_PRINT("GHOST_SystemWin32::wndProc: key event ")
@@ -847,7 +866,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                         * a dead key that is pressed while holding down the alt key.
                                         * To prevent the sound, DefWindowProc must be avoided by return
                                         */
-                                       return 0;
+                                       break;
+                               case WM_SYSCOMMAND:
+                                       /* The WM_SYSCHAR message is sent to the window when system commands such as 
+                                        * maximize, minimize  or close the window are triggered. Also it is sent when ALT 
+                                        * button is press for menu. To prevent this we must return preventing DefWindowProc.
+                                        */
+                                       if(wParam==SC_KEYMENU) return 0;
+                                       break;
                                ////////////////////////////////////////////////////////////////////////
                                // Tablet events, processed
                                ////////////////////////////////////////////////////////////////////////
@@ -1047,8 +1073,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                         * DestroyWindow function sends the WM_NCDESTROY message to the window following the WM_DESTROY
                                         * message. WM_DESTROY is used to free the allocated memory object associated with the window. 
                                         */
+                                       break;
                                case WM_KILLFOCUS:
-                                       /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. */
+                                       /* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard focus. 
+                                        * We want to prevent this if a window is still active and it loses focus to nowhere*/
+                                       if(!wParam && hwnd==GetActiveWindow())
+                                               SetFocus(hwnd);
                                case WM_SHOWWINDOW:
                                        /* The WM_SHOWWINDOW message is sent to a window when the window is about to be hidden or shown. */
                                case WM_WINDOWPOSCHANGING:
@@ -1196,3 +1226,32 @@ void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const
                return;
        }
 }
+
+int GHOST_SystemWin32::toggleConsole(int action)
+{
+       switch(action)
+       {
+               case 3: //hide if no console
+                       {
+                       CONSOLE_SCREEN_BUFFER_INFO csbi = {{0}};
+                       if(!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) || csbi.dwCursorPosition.X || csbi.dwCursorPosition.Y>1)
+                               break;
+                       }
+               case 0: //hide
+                       ShowWindow(GetConsoleWindow(),SW_HIDE);
+                       m_consoleStatus = 0;
+                       break;
+               case 1: //show
+                       ShowWindow(GetConsoleWindow(),SW_SHOW);
+                       m_consoleStatus = 1;
+                       break;
+               case 2: //toggle
+                       ShowWindow(GetConsoleWindow(),m_consoleStatus?SW_HIDE:SW_SHOW);
+                       m_consoleStatus=!m_consoleStatus;
+                       break;
+
+       };
+
+
+       return m_consoleStatus;
+}
index d79b9a22b698236b20f0d92e416d5b33ef74592a..2dad3a6f44d768e94c90c1e97ac1d74804bd7ffa 100644 (file)
@@ -415,6 +415,17 @@ protected:
         * Initiates WM_INPUT messages from keyboard 
         */
        GHOST_TInt32 initKeyboardRawInput(void);
+
+       /**
+ * Toggles console
+ * @action     0 - Hides
+ *                     1 - Shows
+ *                     2 - Toggles
+ *                     3 - Hides if it runs not from  command line
+ *                     * - Does nothing
+ * @return current status (1 -visible, 0 - hidden)
+ */
+       int toggleConsole(int action);
        
        /** The current state of the modifier keys. */
        GHOST_ModifierKeys m_modifierKeys;
@@ -431,6 +442,9 @@ protected:
        /** stores keyboard layout. */
        HKL m_keylayout;
 
+       /** Console status */
+       int m_consoleStatus;
+
        /** handle for user32.dll*/
        HMODULE user32;
        #ifdef NEED_RAW_PROC
@@ -471,6 +485,5 @@ inline void GHOST_SystemWin32::handleKeyboardChange(void)
                }
        }
 }
-
 #endif // _GHOST_SYSTEM_WIN32_H_
 
index e2ee7044392810ca8d2494b615aa9c595a3a598b..378bc6b90beeb56f068a61d5a48ae495c0ca1602 100644 (file)
@@ -1485,10 +1485,8 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const
                        txt_select_buffer = (char*) malloc(strlen(buffer)+1);
                        strcpy(txt_select_buffer, buffer);
                }
-       
+
                if (owner != m_window)
                        fprintf(stderr, "failed to own primary\n");
        }
 }
-
-
index d0e7265951799a4f2381397d9c332d20bca04d80..0b00127363440534d33577ad13e147bf2bfe3d7e 100644 (file)
@@ -227,6 +227,11 @@ public:
         */
        void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
 
+       /**
+        * @see GHOST_ISystem
+        */
+       int toggleConsole(int action) { return 0; }
+
        /**
         * Atom used for ICCCM, WM-spec and Motif.
         * We only need get this atom at the start, it's relative
index 5d21edb758de89184313b04b92aa5880aebefe64..aae1509fda15ec3d5aeb9526a3ce810e7bef3002 100644 (file)
@@ -132,6 +132,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
        GHOST_TDrawingContextType type,
        const bool stereoVisual,
        const GHOST_TUns16 numOfAASamples,
+       GHOST_TEmbedderWindowID parentwindowhwnd,
        GHOST_TSuccess msEnabled,
        int msPixelFormat)
 :
@@ -149,6 +150,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
        m_tablet(0),
        m_maxPressure(0),
        m_multisample(numOfAASamples),
+       m_parentWindowHwnd(parentwindowhwnd),
        m_multisampleEnabled(msEnabled),
        m_msPixelFormat(msPixelFormat),
        //For recreation
@@ -223,15 +225,26 @@ GHOST_WindowWin32::GHOST_WindowWin32(
                else if(top < monitor.rcWork.top)
                        top = monitor.rcWork.top;
 
+               int wintype = WS_OVERLAPPEDWINDOW;
+               if (m_parentWindowHwnd != 0)
+               {
+                       wintype = WS_CHILD;
+                       GetWindowRect((HWND)m_parentWindowHwnd, &rect);
+                       left = 0;
+                       top = 0;
+                       width = rect.right - rect.left;
+                       height = rect.bottom - rect.top;
+               }
+               
                m_hWnd = ::CreateWindow(
                        s_windowClassName,                      // pointer to registered class name
                        title,                                          // pointer to window name
-                       WS_OVERLAPPEDWINDOW,            // window style
+                       wintype,                                        // window style
                        left,                                   // horizontal position of window
                        top,                                    // vertical position of window
                        width,                                          // window width
                        height,                                         // window height
-                       HWND_DESKTOP,                           // handle to parent or owner window
+                       (HWND) m_parentWindowHwnd,      // handle to parent or owner window
                        0,                                                      // handle to menu or child-window identifier
                        ::GetModuleHandle(0),           // handle to application instance
                        0);                                                     // pointer to window-creation data
@@ -294,6 +307,15 @@ GHOST_WindowWin32::GHOST_WindowWin32(
                }
        }
 
+       if (parentwindowhwnd != 0) {
+               RAWINPUTDEVICE device = {0};
+               device.usUsagePage      = 0x01; /* usUsagePage & usUsage for keyboard*/
+               device.usUsage          = 0x06; /* http://msdn.microsoft.com/en-us/windows/hardware/gg487473.aspx */
+               device.dwFlags |= RIDEV_INPUTSINK; // makes WM_INPUT is visible for ghost when has parent window
+               device.hwndTarget = m_hWnd;
+               RegisterRawInputDevices(&device, 1, sizeof(device));
+       }
+
        m_wintab = ::LoadLibrary("Wintab32.dll");
        if (m_wintab) {
                GHOST_WIN32_WTInfo fpWTInfo = ( GHOST_WIN32_WTInfo ) ::GetProcAddress( m_wintab, "WTInfoA" );
@@ -452,6 +474,11 @@ void GHOST_WindowWin32::getClientBounds(GHOST_Rect& bounds) const
                        bounds.m_l = rect.left + sm_cysizeframe;
                        bounds.m_r = rect.right - sm_cysizeframe;
                        bounds.m_t = rect.top;
+               } else if (state == GHOST_kWindowStateEmbedded) {
+                       bounds.m_b = rect.bottom;
+                       bounds.m_l = rect.left;
+                       bounds.m_r = rect.right;
+                       bounds.m_t = rect.top;
                } else {
                        bounds.m_b = rect.bottom-GetSystemMetrics(SM_CYCAPTION)-sm_cysizeframe*2;
                        bounds.m_l = rect.left;
@@ -459,7 +486,6 @@ void GHOST_WindowWin32::getClientBounds(GHOST_Rect& bounds) const
                        bounds.m_t = rect.top;
                }
        } else {
-               ::GetWindowRect(m_hWnd, &rect);
                bounds.m_b = rect.bottom;
                bounds.m_l = rect.left;
                bounds.m_r = rect.right;
@@ -528,6 +554,15 @@ GHOST_TSuccess GHOST_WindowWin32::setClientSize(GHOST_TUns32 width, GHOST_TUns32
 GHOST_TWindowState GHOST_WindowWin32::getState() const
 {
        GHOST_TWindowState state;
+
+       // XXX 27.04.2011
+       // we need to find a way to combine parented windows + resizing if we simply set the
+       // state as GHOST_kWindowStateEmbedded we will need to check for them somewhere else.
+       // It's also strange that in Windows is the only platform we need to make this separation.
+       if (m_parentWindowHwnd != 0) {
+               state = GHOST_kWindowStateEmbedded;
+               return state;
+       }
        if (::IsIconic(m_hWnd)) {
                state = GHOST_kWindowStateMinimized;
        }
@@ -589,6 +624,9 @@ GHOST_TSuccess GHOST_WindowWin32::setState(GHOST_TWindowState state)
                wp.ptMaxPosition.y = 0;
                SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_POPUP | WS_MAXIMIZE);
                break;
+       case GHOST_kWindowStateEmbedded:
+               SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_CHILD);
+               break;
        case GHOST_kWindowStateNormal:
        default:
                ShowWindow(m_hWnd, SW_HIDE);
@@ -651,10 +689,11 @@ GHOST_TSuccess GHOST_WindowWin32::invalidate()
 GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
 {
        int pixelFormat;
-       bool success;
+       bool success = FALSE;
        UINT numFormats;
        HDC hDC = GetDC(getHWND());
        float fAttributes[] = {0, 0};
+       UINT nMaxFormats = 1;
 
        // The attributes to look for
        int iAttributes[] = {
@@ -679,36 +718,24 @@ GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
                return GHOST_kFailure;
        }
 
-       // See if the format is valid
-       success = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
-
-       if (success && numFormats >= 1)
-       {
-               m_multisampleEnabled = GHOST_kSuccess;
-               m_msPixelFormat = pixelFormat;
-               return GHOST_kSuccess;
-       }
-       else
-       {
-               // See if any formats are supported
-               while (!success && iAttributes[19] != 0)
-               {
-                       iAttributes[19] /= 2;
-
-                       success = wglChoosePixelFormatARB(m_hDC, iAttributes, fAttributes, 1, &pixelFormat, &numFormats);
+       // iAttributes[17] is the initial multisample. If not valid try to use the closest valid value under it.
+       while (iAttributes[17] > 0) {
+               // See if the format is valid
+               success = wglChoosePixelFormatARB(hDC, iAttributes, fAttributes, nMaxFormats, &pixelFormat, &numFormats);
+               GHOST_PRINTF("WGL_SAMPLES_ARB = %i --> success = %i, %i formats\n", iAttributes[17], success, numFormats);
 
-                       if (success && numFormats >= 1)
-                       {
-                               m_multisampleEnabled = GHOST_kSuccess;
-                               m_msPixelFormat = pixelFormat;
-                               return GHOST_kSuccess;
-                       }
-
-                       success = GHOST_kFailure;
+               if (success && numFormats >= 1 && m_multisampleEnabled == GHOST_kFailure) {
+                       GHOST_PRINTF("valid pixel format with %i multisamples\n", iAttributes[17]);
+                       m_multisampleEnabled = GHOST_kSuccess;
+                       m_msPixelFormat = pixelFormat;
                }
+               iAttributes[17] -= 1;
+               success = GHOST_kFailure;
        }
-
-       // No available pixel format...
+       if (m_multisampleEnabled == GHOST_kSuccess)     {
+               return GHOST_kSuccess;
+       }
+       GHOST_PRINT("no available pixel format\n");
        return GHOST_kFailure;
 }
 
@@ -856,12 +883,17 @@ GHOST_TSuccess GHOST_WindowWin32::installDrawingContext(GHOST_TDrawingContextTyp
                                                                                                        type,
                                                                                                        m_stereo,
                                                                                                        m_multisample,
+                                                                                                       m_parentWindowHwnd,
                                                                                                        m_multisampleEnabled,
                                                                                                        m_msPixelFormat);
 
                                        // Return failure so we can trash this window.
                                        success = GHOST_kFailure;
                                        break;
+                               } else {
+                                       m_multisampleEnabled = GHOST_kSuccess;
+                                       printf("Multisample failed to initialized\n");
+                                       success = GHOST_kSuccess;
                                }
                        }
                }
index 20212bbc2afd6d45f86dcbbe2981929ababcc5bc..4055c3acf56ed1e4e99a38ac836bfec982e12d56 100644 (file)
@@ -100,6 +100,7 @@ public:
                GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
                const bool stereoVisual = false,
                const GHOST_TUns16 numOfAASamples = 0,
+               GHOST_TEmbedderWindowID parentWindowHwnd=0,
                GHOST_TSuccess msEnabled = GHOST_kFailure,
                int msPixelFormat = 0
        );
@@ -391,6 +392,9 @@ protected:
 
        /** The GHOST_System passes this to wm if this window is being replaced */
        GHOST_Window *m_nextWindow;
+
+       /** Hwnd to parent window */
+       GHOST_TEmbedderWindowID m_parentWindowHwnd;
 };
 
 #endif // _GHOST_WINDOW_WIN32_H_
index 9a29b713882b5985152712756dc9f9fa3c88779c..f7e5b988cc8e3e80b5a313dc4c6229aea3eac668 100644 (file)
@@ -144,6 +144,9 @@ def resolve_ncase(path):
             dirpath = os.path.dirname(dirpath)
 
         if not os.path.exists(dirpath):
+            if dirpath == path:
+                return path, False
+
             dirpath, found = _ncase_path_found(dirpath)
 
             if not found:
index eee98bdca37229b0788851524b6fcd35347376f4..a2d7b9e502f6ecbce30440514e6a2f049a5aaecf 100644 (file)
@@ -33,6 +33,8 @@ import sys as _sys
 
 import addon_utils as _addon_utils
 
+_script_module_dirs = "startup", "modules"
+
 
 def _test_import(module_name, loaded_modules):
     use_time = _bpy.app.debug
@@ -183,7 +185,7 @@ def load_scripts(reload_scripts=False, refresh_scripts=False):
         _global_loaded_modules[:] = []
 
     for base_path in script_paths():
-        for path_subdir in ("startup", "modules"):
+        for path_subdir in _script_module_dirs:
             path = _os.path.join(base_path, path_subdir)
             if _os.path.isdir(path):
                 _sys_path_ensure(path)
@@ -226,27 +228,41 @@ def user_script_path():
         return None
 
 
-def script_paths(subdir=None, user=True):
+def script_paths(subdir=None, user_pref=True, all=False):
     """
-    Returns a list of valid script paths from the home directory and user preferences.
+    Returns a list of valid script paths.
 
-    Accepts any number of string arguments which are joined to make a path.
+    :arg subdir: Optional subdir.
+    :type subdir: string
+    :arg user_pref: Include the user preference script path.
+    :type user_pref: bool
+    :arg all: Include local, user and system paths rather just the paths blender uses.
+    :type all: bool
+    :return: script paths.
+    :rtype: list
     """
     scripts = list(_scripts)
 
     # add user scripts dir
-    if user:
+    if user_pref:
         user_script_path = _bpy.context.user_preferences.filepaths.script_directory
     else:
         user_script_path = None
 
-    for path in _bpy_script_paths() + (user_script_path, ):
+    if all:
+        # all possible paths
+        base_paths = tuple(_os.path.join(resource_path(res), "scripts") for res in ('LOCAL', 'USER', 'SYSTEM'))
+    else:
+        # only paths blender uses
+        base_paths = _bpy_script_paths()
+
+    for path in base_paths + (user_script_path, ):
         if path:
             path = _os.path.normpath(path)
             if path not in scripts and _os.path.isdir(path):
                 scripts.append(path)
 
-    if not subdir:
+    if subdir is None:
         return scripts
 
     script_paths = []
@@ -258,6 +274,24 @@ def script_paths(subdir=None, user=True):
     return script_paths
 
 
+def refresh_script_paths():
+    """
+    Run this after creating new script paths to update sys.path
+    """
+
+    for base_path in script_paths():
+        for path_subdir in _script_module_dirs:
+            path = _os.path.join(base_path, path_subdir)
+            if _os.path.isdir(path):
+                _sys_path_ensure(path)
+
+    for path in _addon_utils.paths():
+        _sys_path_ensure(path)
+        path = _os.path.join(path, "modules")
+        if _os.path.isdir(path):
+            _sys_path_ensure(path)
+
+
 _presets = _os.path.join(_scripts[0], "presets")  # FIXME - multiple paths
 
 
@@ -266,7 +300,7 @@ def preset_paths(subdir):
     Returns a list of paths for a specific preset.
     """
     dirs = []
-    for path in script_paths("presets"):
+    for path in script_paths("presets", all=True):
         directory = _os.path.join(path, subdir)
         if _os.path.isdir(directory):
             dirs.append(directory)
index 4fcfcfbd0a9dd6af57db91e7f1c33d8c39bee33d..820d7cfa39d18b1dd4d65d7a18f16a514508e610 100644 (file)
@@ -67,6 +67,86 @@ class ImportHelper:
         return {'RUNNING_MODAL'}
 
 
+# Axis conversion function, not pretty LUT
+# use lookup tabes to convert between any axis
+_axis_convert_matrix = (
+    ((-1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, 1.0)),
+    ((-1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, -1.0, 0.0)),
+    ((-1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, 1.0, 0.0)),
+    ((-1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (0.0, 0.0, -1.0)),
+    ((0.0, -1.0, 0.0), (-1.0, 0.0, 0.0), (0.0, 0.0, -1.0)),
+    ((0.0, -1.0, 0.0), (0.0, 0.0, -1.0), (1.0, 0.0, 0.0)),
+    ((0.0, -1.0, 0.0), (0.0, 0.0, 1.0), (-1.0, 0.0, 0.0)),
+    ((0.0, -1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, 1.0)),
+    ((0.0, 0.0, -1.0), (-1.0, 0.0, 0.0), (0.0, 1.0, 0.0)),
+    ((0.0, 0.0, -1.0), (0.0, -1.0, 0.0), (-1.0, 0.0, 0.0)),
+    ((0.0, 0.0, -1.0), (0.0, 1.0, 0.0), (1.0, 0.0, 0.0)),
+    ((0.0, 0.0, -1.0), (1.0, 0.0, 0.0), (0.0, -1.0, 0.0)),
+    ((0.0, 0.0, 1.0), (-1.0, 0.0, 0.0), (0.0, -1.0, 0.0)),
+    ((0.0, 0.0, 1.0), (0.0, -1.0, 0.0), (1.0, 0.0, 0.0)),
+    ((0.0, 0.0, 1.0), (0.0, 1.0, 0.0), (-1.0, 0.0, 0.0)),
+    ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0)),
+    ((0.0, 1.0, 0.0), (-1.0, 0.0, 0.0), (0.0, 0.0, 1.0)),
+    ((0.0, 1.0, 0.0), (0.0, 0.0, -1.0), (-1.0, 0.0, 0.0)),
+    ((0.0, 1.0, 0.0), (0.0, 0.0, 1.0), (1.0, 0.0, 0.0)),
+    ((0.0, 1.0, 0.0), (1.0, 0.0, 0.0), (0.0, 0.0, -1.0)),
+    ((1.0, 0.0, 0.0), (0.0, -1.0, 0.0), (0.0, 0.0, -1.0)),
+    ((1.0, 0.0, 0.0), (0.0, 0.0, -1.0), (0.0, 1.0, 0.0)),
+    ((1.0, 0.0, 0.0), (0.0, 0.0, 1.0), (0.0, -1.0, 0.0)),
+    )
+
+# store args as a single int
+# (X Y Z -X -Y -Z) --> (0, 1, 2, 3, 4, 5)
+# each value is ((src_forward, src_up), (dst_forward, dst_up))
+# where all 4 values are or'd into a single value...
+#    (i1<<0 | i1<<3 | i1<<6 | i1<<9)
+_axis_convert_lut = (
+    {0x5c, 0x9a, 0x119, 0x15d, 0x20b, 0x2a2, 0x2c8, 0x365, 0x413, 0x46c, 0x4d0, 0x529, 0x644, 0x682, 0x701, 0x745, 0x823, 0x88a, 0x8e0, 0x94d, 0xa2b, 0xa54, 0xae8, 0xb11},
+    {0x9c, 0xac, 0x159, 0x169, 0x22b, 0x2e8, 0x40b, 0x465, 0x4c8, 0x522, 0x684, 0x694, 0x741, 0x751, 0x813, 0x8d0, 0xa23, 0xa4d, 0xae0, 0xb0a},
+    {0x99, 0xa9, 0x15c, 0x16c, 0x213, 0x2d0, 0x423, 0x44a, 0x4e0, 0x50d, 0x681, 0x691, 0x744, 0x754, 0x82b, 0x8e8, 0xa0b, 0xa62, 0xac8, 0xb25},
+    {0x59, 0x85, 0x11c, 0x142, 0x223, 0x28d, 0x2e0, 0x34a, 0x42b, 0x469, 0x4e8, 0x52c, 0x641, 0x69d, 0x704, 0x75a, 0x80b, 0x8a5, 0x8c8, 0x962, 0xa13, 0xa51, 0xad0, 0xb14},
+    {0xa5, 0x162, 0x21c, 0x285, 0x2d9, 0x342, 0x463, 0x46b, 0x520, 0x528, 0x68d, 0x74a, 0x804, 0x89d, 0x8c1, 0x95a, 0xa4b, 0xa53, 0xb08, 0xb10},
+    {0x4b, 0x53, 0x108, 0x110, 0x29c, 0x2ac, 0x359, 0x369, 0x41a, 0x422, 0x4dd, 0x4e5, 0x663, 0x66b, 0x720, 0x728, 0x884, 0x894, 0x941, 0x951, 0xa02, 0xa0a, 0xac5, 0xacd},
+    {0x63, 0x6b, 0x120, 0x128, 0x299, 0x2a9, 0x35c, 0x36c, 0x405, 0x40d, 0x4c2, 0x4ca, 0x64b, 0x653, 0x708, 0x710, 0x881, 0x891, 0x944, 0x954, 0xa1d, 0xa25, 0xada, 0xae2},
+    {0x8a, 0x14d, 0x219, 0x29a, 0x2dc, 0x35d, 0x44b, 0x453, 0x508, 0x510, 0x6a2, 0x765, 0x801, 0x882, 0x8c4, 0x945, 0xa63, 0xa6b, 0xb20, 0xb28},
+    {0x5a, 0x62, 0x8b, 0x11d, 0x125, 0x148, 0x22c, 0x28b, 0x293, 0x2e9, 0x348, 0x350, 0x41c, 0x42c, 0x45a, 0x4d9, 0x4e9, 0x51d, 0x642, 0x64a, 0x6a3, 0x705, 0x70d, 0x760, 0x814, 0x8a3, 0x8ab, 0x8d1, 0x960, 0x968, 0xa04, 0xa14, 0xa42, 0xac1, 0xad1, 0xb05},
+    {0x54, 0xab, 0x111, 0x168, 0x21d, 0x225, 0x2da, 0x2e2, 0x45c, 0x519, 0x66c, 0x693, 0x729, 0x750, 0x805, 0x80d, 0x8c2, 0x8ca, 0xa44, 0xb01},
+    {0x51, 0x93, 0x114, 0x150, 0x202, 0x20a, 0x2c5, 0x2cd, 0x459, 0x51c, 0x669, 0x6ab, 0x72c, 0x768, 0x81a, 0x822, 0x8dd, 0x8e5, 0xa41, 0xb04},
+    {0x45, 0x4d, 0xa3, 0x102, 0x10a, 0x160, 0x229, 0x2a3, 0x2ab, 0x2ec, 0x360, 0x368, 0x419, 0x429, 0x445, 0x4dc, 0x4ec, 0x502, 0x65d, 0x665, 0x68b, 0x71a, 0x722, 0x748, 0x811, 0x88b, 0x893, 0x8d4, 0x948, 0x950, 0xa01, 0xa11, 0xa5d, 0xac4, 0xad4, 0xb1a},
+    {0x5d, 0x65, 0xa0, 0x11a, 0x122, 0x163, 0x214, 0x2a0, 0x2a8, 0x2d1, 0x363, 0x36b, 0x404, 0x414, 0x45d, 0x4c1, 0x4d1, 0x51a, 0x645, 0x64d, 0x688, 0x702, 0x70a, 0x74b, 0x82c, 0x888, 0x890, 0x8e9, 0x94b, 0x953, 0xa1c, 0xa2c, 0xa45, 0xad9, 0xae9, 0xb02},
+    {0x6c, 0x90, 0x129, 0x153, 0x21a, 0x222, 0x2dd, 0x2e5, 0x444, 0x501, 0x654, 0x6a8, 0x711, 0x76b, 0x802, 0x80a, 0x8c5, 0x8cd, 0xa5c, 0xb19},
+    {0x69, 0xa8, 0x12c, 0x16b, 0x205, 0x20d, 0x2c2, 0x2ca, 0x441, 0x504, 0x651, 0x690, 0x714, 0x753, 0x81d, 0x825, 0x8da, 0x8e2, 0xa59, 0xb1c},
+    {0x42, 0x4a, 0x88, 0x105, 0x10d, 0x14b, 0x211, 0x288, 0x290, 0x2d4, 0x34b, 0x353, 0x401, 0x411, 0x442, 0x4c4, 0x4d4, 0x505, 0x65a, 0x662, 0x6a0, 0x71d, 0x725, 0x763, 0x829, 0x8a0, 0x8a8, 0x8ec, 0x963, 0x96b, 0xa19, 0xa29, 0xa5a, 0xadc, 0xaec, 0xb1d},
+    {0xa2, 0x165, 0x204, 0x282, 0x2c1, 0x345, 0x448, 0x450, 0x50b, 0x513, 0x68a, 0x74d, 0x81c, 0x89a, 0x8d9, 0x95d, 0xa60, 0xa68, 0xb23, 0xb2b},
+    {0x60, 0x68, 0x123, 0x12b, 0x284, 0x294, 0x341, 0x351, 0x41d, 0x425, 0x4da, 0x4e2, 0x648, 0x650, 0x70b, 0x713, 0x89c, 0x8ac, 0x959, 0x969, 0xa05, 0xa0d, 0xac2, 0xaca},
+    {0x48, 0x50, 0x10b, 0x113, 0x281, 0x291, 0x344, 0x354, 0x402, 0x40a, 0x4c5, 0x4cd, 0x660, 0x668, 0x723, 0x72b, 0x899, 0x8a9, 0x95c, 0x96c, 0xa1a, 0xa22, 0xadd, 0xae5},
+    {0x8d, 0x14a, 0x201, 0x29d, 0x2c4, 0x35a, 0x460, 0x468, 0x523, 0x52b, 0x6a5, 0x762, 0x819, 0x885, 0x8dc, 0x942, 0xa48, 0xa50, 0xb0b, 0xb13},
+    {0x44, 0x9d, 0x101, 0x15a, 0x220, 0x2a5, 0x2e3, 0x362, 0x428, 0x454, 0x4eb, 0x511, 0x65c, 0x685, 0x719, 0x742, 0x808, 0x88d, 0x8cb, 0x94a, 0xa10, 0xa6c, 0xad3, 0xb29},
+    {0x84, 0x94, 0x141, 0x151, 0x210, 0x2d3, 0x420, 0x462, 0x4e3, 0x525, 0x69c, 0x6ac, 0x759, 0x769, 0x828, 0x8eb, 0xa08, 0xa4a, 0xacb, 0xb0d},
+    {0x81, 0x91, 0x144, 0x154, 0x228, 0x2eb, 0x408, 0x44d, 0x4cb, 0x50a, 0x699, 0x6a9, 0x75c, 0x76c, 0x810, 0x8d3, 0xa20, 0xa65, 0xae3, 0xb22},
+    )
+
+_axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
+
+
+def axis_conversion(from_forward='Y', from_up='Z', to_forward='Y', to_up='Z'):
+    """
+    Each argument us an axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z']
+    where the first 2 are a source and the second 2 are the target.
+    """
+    from mathutils import Matrix
+    from functools import reduce
+
+    if from_forward == to_forward and from_up == to_up:
+        return Matrix().to_3x3()
+
+    value = reduce(int.__or__, (_axis_convert_num[a] << (i * 3) for i, a in enumerate((from_forward, from_up, to_forward, to_up))))
+    for i, axis_lut in enumerate(_axis_convert_lut):
+        if value in axis_lut:
+            return Matrix(_axis_convert_matrix[i])
+    assert("internal error")
+
+
 # limited replacement for BPyImage.comprehensiveImageLoad
 def load_image(imagepath, dirname):
     import os
@@ -198,7 +278,7 @@ def path_reference(filepath, base_src, base_dst, mode='AUTO', copy_subdir="", co
 def path_reference_copy(copy_set, report=print):
     """
     Execute copying files of path_reference
-    
+
     :arg copy_set: set of (from, to) pairs to copy.
     :type copy_set: set
     :arg report: function used for reporting warnings, takes a string argument.
index aa6a11407af0a37d87ee8099210a21fa755a2add..493c51ad2379ae2f170da9f399adc82ab0cc383f 100644 (file)
@@ -48,11 +48,11 @@ class AddPresetBase():
         preset_menu_class = getattr(bpy.types, self.preset_menu)
 
         if not self.remove_active:
-
-            if not self.name:
+            name = self.name.strip()
+            if not name:
                 return {'FINISHED'}
 
-            filename = self.as_filename(self.name)
+            filename = self.as_filename(name)
 
             target_path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", self.preset_subdir), create=True)
 
@@ -118,7 +118,7 @@ class AddPresetBase():
         return {'FINISHED'}
 
     def check(self, context):
-        self.name = self.as_filename(self.name)
+        self.name = self.as_filename(self.name.strip())
 
     def invoke(self, context, event):
         if not self.remove_active:
@@ -327,7 +327,7 @@ class AddPresetOperator(AddPresetBase, bpy.types.Operator):
         ret = []
         for prop_id, prop in operator_rna.properties.items():
             if (not prop.is_hidden) and prop_id not in properties_blacklist:
-                    ret.append("op.%s" % prop_id)
+                ret.append("op.%s" % prop_id)
 
         return ret
 
index d02b2bfbdde1aee001f5e9611b8bf69d9a5e5ff0..53c8d56229717ee43a6cd3b263ad3a4a54e61297 100644 (file)
@@ -837,6 +837,7 @@ class WM_OT_properties_add(bpy.types.Operator):
         item[property] = 1.0
         return {'FINISHED'}
 
+
 class WM_OT_properties_context_change(bpy.types.Operator):
     "Change the context tab in a Properties Window"
     bl_idname = "wm.properties_context_change"
@@ -846,7 +847,6 @@ class WM_OT_properties_context_change(bpy.types.Operator):
 
     def execute(self, context):
         context.space_data.context = (self.context)
-               
         return {'FINISHED'}
 
 
index e640654ea69ae94216c216bd2eab0f9bd0519a5e..27af84dbcfb2b985978555f7a5239097e28fbbdb 100644 (file)
@@ -581,7 +581,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
         col.prop(md, "use_even_offset")
         col.prop(md, "use_quality_normals")
         col.prop(md, "use_rim")
-        
+
         sub = col.column()
         sub.label()
         row = sub.split(align=True, percentage=0.4)
@@ -635,6 +635,48 @@ class DATA_PT_modifiers(ModifierButtonsPanel, bpy.types.Panel):
             sub.prop(md, "scale_x", text="Scale X")
             sub.prop(md, "scale_y", text="Scale Y")
 
+    def WARP(self, layout, ob, md):
+        use_falloff = (md.falloff_type != 'NONE')
+        split = layout.split()
+
+        col = split.column()
+        col.label(text="From:")
+        col.prop(md, "object_from", text="")
+
+        col.prop(md, "use_volume_preserve")
+
+        col = split.column()
+        col.label(text="To:")
+        col.prop(md, "object_to", text="")
+        col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
+
+        col = layout.column()
+
+        row = col.row(align=True)
+        row.prop(md, "strength")
+        if use_falloff:
+            row.prop(md, "falloff_radius")
+
+        col.prop(md, "falloff_type")
+        if use_falloff:
+            if md.falloff_type == 'CURVE':
+                col.template_curve_mapping(md, "falloff_curve")
+
+        # 2 new columns
+        split = layout.split()
+        col = split.column()
+        col.label(text="Texture:")
+        col.prop(md, "texture", text="")
+
+        col = split.column()
+        col.label(text="Texture Coordinates:")
+        col.prop(md, "texture_coords", text="")
+
+        if md.texture_coords == 'OBJECT':
+            layout.prop(md, "texture_coordinate_object", text="Object")
+        elif md.texture_coords == 'UV' and ob.type == 'MESH':
+            layout.prop_search(md, "uv_layer", ob.data, "uv_textures")
+
     def WAVE(self, layout, ob, md):
         split = layout.split()
 
index a151234e184c6cf3c25d61b431a1caad882d47f9..0c07451b3b2dcdde62413053dbe48b305765863c 100644 (file)
@@ -323,6 +323,7 @@ class RENDER_PT_game_shading(RenderButtonsPanel, bpy.types.Panel):
             col.prop(gs, "use_glsl_lights", text="Lights")
             col.prop(gs, "use_glsl_shaders", text="Shaders")
             col.prop(gs, "use_glsl_shadows", text="Shadows")
+            col.prop(gs, "use_glsl_color_management", text="Color Management")
 
             col = split.column()
             col.prop(gs, "use_glsl_ramps", text="Ramps")
index 0443a351afab951e26bc4439b097bd7f84983d9c..52d6b5f1376e257e10cfacdbd1b469349868c6fd 100644 (file)
@@ -549,6 +549,7 @@ class MATERIAL_PT_halo(MaterialButtonsPanel, bpy.types.Panel):
         col = split.column()
         col.prop(mat, "alpha")
         col.prop(mat, "diffuse_color", text="")
+        col.prop(halo, "seed")
 
         col = split.column()
         col.prop(halo, "size")
index 5c7882e97229e4546e1df9fb304f983dc87da2fd..bce6ab993a7fd8a3fa5745a6beaffe7de7684f92 100644 (file)
@@ -157,6 +157,8 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, bpy.types.Panel):
         col = split.column()
         col.prop(cloth, "collision_quality", slider=True, text="Quality")
         col.prop(cloth, "distance_min", slider=True, text="Distance")
+        col.prop(cloth, "repel_force", slider=True, text="Repel")
+        col.prop(cloth, "distance_repel", slider=True, text="Repel Distance")
         col.prop(cloth, "friction")
 
         col = split.column()
index be46eb5dca6c1a876500b55a16cfcf26fa7364c9..01890bc3c99d0de455187eeda020ff178d25af44 100644 (file)
@@ -723,9 +723,9 @@ class TEXTURE_PT_pointdensity(TextureButtonsPanel, bpy.types.Panel):
             col.prop(pd, "falloff_soft")
         if pd.falloff == "PARTICLE_VELOCITY":
             col.prop(pd, "falloff_speed_scale")
-        
+
         col.prop(pd, "use_falloff_curve")
-        
+
         if pd.use_falloff_curve:
             col = layout.column()
             col.label(text="Falloff Curve")
index da6318ed39e6339c3d4a35d7503813a78e3c95a8..77583b8082476aa173f13d4a74aceb5c28c21e0c 100644 (file)
@@ -370,10 +370,7 @@ class IMAGE_HT_header(bpy.types.Header):
             layout.prop(toolsettings, "use_uv_select_sync", text="")
 
             if toolsettings.use_uv_select_sync:
-                row = layout.row(align=True)
-                row.prop(toolsettings, "mesh_select_mode", text="", index=0, icon='VERTEXSEL')
-                row.prop(toolsettings, "mesh_select_mode", text="", index=1, icon='EDGESEL')
-                row.prop(toolsettings, "mesh_select_mode", text="", index=2, icon='FACESEL')
+                layout.template_edit_mode_selection()
             else:
                 layout.prop(toolsettings, "uv_select_mode", text="", expand=True)
                 layout.prop(uvedit, "sticky_select_mode", text="", icon_only=True)
index 3d3fc8499af07333ef190bb851c30f8bf2fe3cf3..5b07e8dc37f8f7a6834eb5eaa71d4783539b3bb4 100644 (file)
@@ -129,6 +129,7 @@ class TEXT_PT_find(bpy.types.Panel):
         layout.operator("text.mark_all")
 
         # settings
+        layout.prop(st, "use_match_case")
         row = layout.row()
         row.prop(st, "use_find_wrap", text="Wrap")
         row.prop(st, "use_find_all", text="All")
index 7ae2efb369694b203c7bf3a860b5cb2cc30769ed..bf396e98c79b371d6a61d5266d815cdc8841809c 100644 (file)
@@ -1103,7 +1103,8 @@ class WM_OT_addon_install(bpy.types.Operator):
         del pyfile_dir
         # done checking for exceptional case
 
-        contents = set(os.listdir(path_addons))
+        addon_files_old = set(os.listdir(path_addons))
+        addons_old = {mod.__name__ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules)}
 
         #check to see if the file is in compressed format (.zip)
         if zipfile.is_zipfile(pyfile):
@@ -1152,11 +1153,13 @@ class WM_OT_addon_install(bpy.types.Operator):
                 traceback.print_exc()
                 return {'CANCELLED'}
 
+        addons_new = {mod.__name__ for mod in addon_utils.modules(USERPREF_PT_addons._addons_fake_modules)} - addons_old
+        addons_new.discard("modules")
+
         # disable any addons we may have enabled previously and removed.
         # this is unlikely but do just incase. bug [#23978]
-        addons_new = set(os.listdir(path_addons)) - contents
         for new_addon in addons_new:
-            addon_utils.disable(os.path.splitext(new_addon)[0])
+            addon_utils.disable(new_addon)
 
         # possible the zip contains multiple addons, we could disallow this
         # but for now just use the first
@@ -1169,6 +1172,9 @@ class WM_OT_addon_install(bpy.types.Operator):
                 context.window_manager.addon_search = info["name"]
                 break
 
+        # incase a new module path was created to install this addon.
+        bpy.utils.refresh_script_paths()
+
         # TODO, should not be a warning.
         # self.report({'WARNING'}, "File installed to '%s'\n" % path_dest)
         return {'FINISHED'}
index 2fbaae499e7ccfea5f8dded7b22cbc8a21fc35f0..378fe2310915ce1455045d250c89d726f3987f00 100644 (file)
@@ -555,13 +555,7 @@ class WM_OT_keyconfig_import(bpy.types.Operator):
 
         config_name = basename(self.filepath)
 
-        path = bpy.utils.preset_paths("keyconfig")[0]  # we need some way to tell the user and system preset path
-        print(path)
-
-        # create config folder if needed
-        if not os.path.exists(path):
-            os.mkdir(path)
-
+        path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
         path = os.path.join(path, config_name)
 
         if self.keep_original:
index 2eaac42cf354649ee03cf8b5601469e53e37648c..7d31bc39b0a96f8b809987e583b17986ce5dfef7 100644 (file)
@@ -851,10 +851,15 @@ class VIEW3D_MT_object_apply(bpy.types.Menu):
     def draw(self, context):
         layout = self.layout
 
-        layout.operator("object.location_apply", text="Location")
-        layout.operator("object.rotation_apply", text="Rotation")
-        layout.operator("object.scale_apply", text="Scale")
+        layout.operator("object.transform_apply", text="Location").location = True
+        layout.operator("object.transform_apply", text="Rotation").rotation = True
+        layout.operator("object.transform_apply", text="Scale").scale = True
+        props = layout.operator("object.transform_apply", text="Rotation & Scale")
+        props.scale = True
+        props.rotation = True
+
         layout.separator()
+
         layout.operator("object.visual_transform_apply", text="Visual Transform")
         layout.operator("object.duplicates_make_real")
 
index bd258fa18f62021d43cd1307d46096f90411b337..a6db6fbdde85b4eb35260e9dc85c8c90907858ac 100644 (file)
@@ -946,26 +946,21 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
         sculpt = tool_settings.sculpt
         settings = __class__.paint_settings(context)
 
-        split = layout.split()
-
-        col = split.column()
-
-        col.prop(sculpt, "use_threaded", text="Threaded Sculpt")
-        col.prop(sculpt, "show_low_resolution")
-        col.prop(sculpt, "show_brush")
-
-        col.label(text="Unified Settings:")
-        col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
-        col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
-
-        col = split.column()
-
-        col.label(text="Lock:")
-        row = col.row(align=True)
+        layout.label(text="Lock:")
+        row = layout.row(align=True)
         row.prop(sculpt, "lock_x", text="X", toggle=True)
         row.prop(sculpt, "lock_y", text="Y", toggle=True)
         row.prop(sculpt, "lock_z", text="Z", toggle=True)
 
+        layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
+        layout.prop(sculpt, "show_low_resolution")
+        layout.prop(sculpt, "show_brush")
+        layout.prop(sculpt, "use_deform_only")
+
+        layout.label(text="Unified Settings:")
+        layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
+        layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
+
 
 class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
     bl_label = "Symmetry"
index 1929f19f38f829a61a28b90c94ef3839b1999011..5d0354ccd721e031dd03388f416f05912d943e6f 100644 (file)
@@ -27,7 +27,6 @@
 add_subdirectory(blender)
 
 if(WITH_GAMEENGINE)
-       add_subdirectory(kernel)
        add_subdirectory(gameengine)
 endif()
        
index 8d08d9cca0838a1beb04eb2cb8a360440da3fd6e..0002cb4cf0bef0d363c5c32bea553b534ed42c29 100644 (file)
@@ -4,7 +4,7 @@ Import ('env')
 SConscript(['blender/SConscript', 'creator/SConscript'])
 
 if env['WITH_BF_GAMEENGINE']:
-    SConscript (['kernel/SConscript', 'gameengine/SConscript'])
+    SConscript (['gameengine/SConscript'])
 
 if env['WITH_BF_PLAYER']:
     SConscript (['blenderplayer/bad_level_call_stubs/SConscript'])
index 44d3cf2c61bdc874253e10dbe84462a569d85f8a..57f8c83eda61963661a2820cb9d2e7ecaa65b022 100644 (file)
@@ -90,6 +90,14 @@ void BLF_boundbox(int fontid, const char *str, struct rctf *box);
 float BLF_width(int fontid, const char *str);
 float BLF_height(int fontid, const char *str);
 
+/*
+ * Return dimensions of the font without any sample text.
+ */
+float BLF_height_max(int fontid);
+float BLF_width_max(int fontid);
+float BLF_descender(int fontid);
+float BLF_ascender(int fontid);
+
 /*
  * The following function return the width and height of the string, but
  * just in one call, so avoid extra freetype2 stuff.
index 5db71948024987837688670125a4a7a480d92947..c0e62b1c0c70340d72bcf2b58efbebc2ecc8c33d 100644 (file)
@@ -580,6 +580,54 @@ float BLF_height(int fontid, const char *str)
        return(0.0f);
 }
 
+float BLF_height_max(int fontid)
+{
+       FontBLF *font;
+
+       font= BLF_get(fontid);
+       if (font) {
+               if(font->glyph_cache)
+                       return(font->glyph_cache->max_glyph_height);
+       }
+       return(0.0f);
+}
+
+float BLF_width_max(int fontid)
+{
+       FontBLF *font;
+
+       font= BLF_get(fontid);
+       if (font) {
+               if(font->glyph_cache)
+                       return(font->glyph_cache->max_glyph_width);
+       }
+       return(0.0f);
+}
+
+float BLF_descender(int fontid)
+{
+       FontBLF *font;
+
+       font= BLF_get(fontid);
+       if (font) {
+               if(font->glyph_cache)
+                       return(font->glyph_cache->descender);
+       }
+       return(0.0f);
+}
+
+float BLF_ascender(int fontid)
+{
+       FontBLF *font;
+
+       font= BLF_get(fontid);
+       if (font) {
+               if(font->glyph_cache)
+                       return(font->glyph_cache->ascender);
+       }
+       return(0.0f);
+}
+
 float BLF_height_default(const char *str)
 {
        float height;
index 6c415010953a8096167f60bbc4341ecb3e054bc4..7e9f531162b6173eec6015f80fdfb290783074df 100644 (file)
@@ -53,7 +53,7 @@ extern "C" {
                /* can be left blank, otherwise a,b,c... etc with no quotes */
 #define BLENDER_VERSION_CHAR   b
                /* alpha/beta/rc/release, docs use this */
-#define BLENDER_VERSION_CYCLE  release
+#define BLENDER_VERSION_CYCLE  beta
 
 struct ListBase;
 struct MemFile;
index 1ee51cd2122db196a2dc1559a3da1921a6ee341f..a5c88000db2c251e68e8db2e2cd49061c5f0a69b 100644 (file)
@@ -35,6 +35,7 @@
  */
 
 #include <float.h>
+#include "BLI_math_inline.h"
 
 struct Object;
 struct ListBase;
@@ -44,16 +45,7 @@ struct DerivedMesh;
 struct ClothModifierData;
 struct CollisionTree;
 
-// this is needed for inlining behaviour
-#if defined _WIN32
-#   define DO_INLINE __inline
-#elif defined (__sgi)
-#   define DO_INLINE
-#elif defined (__sun) || defined (__sun__)
-#   define DO_INLINE
-#else
-#   define DO_INLINE static inline
-#endif
+#define DO_INLINE MALWAYS_INLINE
 
 #define CLOTH_MAX_THREAD 2
 
index b54d4275719729ba2480ab0ad6487c274d3dfd68..4048ee2f457e6bf5cc7f60eb0f09c6c9806afa2a 100644 (file)
@@ -63,7 +63,11 @@ struct LinkNode;
 /* COLLISION FLAGS */
 typedef enum
 {
-       COLLISION_IN_FUTURE = ( 1 << 1 ),
+       COLLISION_IN_FUTURE =           (1 << 1),
+#ifdef WITH_ELTOPO
+       COLLISION_USE_COLLFACE =        (1 << 2),
+       COLLISION_IS_EDGES =            (1 << 3),
+#endif
 } COLLISION_FLAGS;
 
 
@@ -81,7 +85,13 @@ typedef struct CollPair
        float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
        int flag;
        float time; // collision time, from 0 up to 1
+#ifdef WITH_ELTOPO /*either ap* or bp* can be set, but not both*/
+       float bary[3];
+       int ap1, ap2, ap3, collp, bp1, bp2, bp3;
+       int collface;
+#else
        int ap1, ap2, ap3, bp1, bp2, bp3;
+#endif
        int pointsb[4];
 }
 CollPair;
@@ -109,6 +119,7 @@ typedef struct FaceCollPair
        float pa[3], pb[3]; // collision point p1 on face1, p2 on face2
 }
 FaceCollPair;
+
 ////////////////////////////////////////
 
 
diff --git a/source/blender/blenkernel/BKE_exotic.h b/source/blender/blenkernel/BKE_exotic.h
deleted file mode 100644 (file)
index 870dd7c..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef BKE_EXOTIC_H
-#define BKE_EXOTIC_H
-
-/** \file BKE_exotic.h
- *  \ingroup bke
- *  \brief dxf/vrml/stl external file io function prototypes.
- *  \attention is this used still? Candidate for removal?
- */
-struct Mesh;
-struct Scene;
-
-/**
- * Reads all 3D fileformats other than Blender fileformat
- * @retval 0 The file could not be read.
- * @retval 1 The file was read succesfully.
- * @attention Used in filesel.c
- */
-int BKE_read_exotic(struct Scene *scene, const char *name);
-
-/* return codes */
-#define BKE_READ_EXOTIC_FAIL_PATH              -3 /* file format is not supported */
-#define BKE_READ_EXOTIC_FAIL_FORMAT            -2 /* file format is not supported */
-#define BKE_READ_EXOTIC_FAIL_OPEN              -1 /* Can't open the file */
-#define BKE_READ_EXOTIC_OK_BLEND                0 /* .blend file */
-#define BKE_READ_EXOTIC_OK_OTHER                1 /* other supported formats */
-
-void write_dxf(struct Scene *scene, char *str);
-void write_stl(struct Scene *scene, char *str);
-
-#endif
-
index 64c29158bd4171bba283ddb4d656baced2cbc574..10910493ec94d467633adce0268ed8ae6dd11d15 100644 (file)
@@ -133,6 +133,7 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf);
 
 /* called on frame change or before render */
 void BKE_image_user_calc_frame(struct ImageUser *iuser, int cfra, int fieldnr);
+int BKE_image_user_get_frame(const struct ImageUser *iuser, int cfra, int fieldnr);
 
 /* fix things in ImageUser when new image gets assigned */
 void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser);
index 136ce4160373ebc4304f10fbe82b52b2bdefcb0f..20e5bc27146f366763a127779faa1473d57c9519 100644 (file)
@@ -58,7 +58,7 @@ void                  write_text(struct Text *text, const char *str);
 char*  txt_to_buf                      (struct Text *text);
 void   txt_clean_text          (struct Text *text);
 void   txt_order_cursors       (struct Text *text);
-int            txt_find_string         (struct Text *text, char *findstr, int wrap);
+int            txt_find_string         (struct Text *text, char *findstr, int wrap, int match_case);
 int            txt_has_sel                     (struct Text *text);
 int            txt_get_span            (struct TextLine *from, struct TextLine *to);
 void   txt_move_up                     (struct Text *text, short sel);
index a619be07b6aeeee77cf2803f7dba37204257033c..0da260c3f2a7e1b567d7cb3141ce24e47557e9eb 100644 (file)
@@ -92,7 +92,6 @@ set(SRC
        intern/depsgraph.c
        intern/displist.c
        intern/effect.c
-       intern/exotic.c
        intern/fcurve.c
        intern/fluidsim.c
        intern/fmodifier.c
@@ -147,7 +146,7 @@ set(SRC
        intern/writeavi.c
        intern/writeffmpeg.c
        intern/writeframeserver.c
-
+       
        BKE_DerivedMesh.h
        BKE_action.h
        BKE_anim.h
@@ -178,7 +177,6 @@ set(SRC
        BKE_displist.h
        BKE_effect.h
        BKE_endian.h
-       BKE_exotic.h
        BKE_fcurve.h
        BKE_fluidsim.h
        BKE_font.h
@@ -242,6 +240,11 @@ if(WITH_BULLET)
        add_definitions(-DUSE_BULLET)
 endif()
 
+if(WITH_MOD_CLOTH_ELTOPO)
+       list(APPEND INC ../../../extern/eltopo)
+       add_definitions(-DWITH_ELTOPO)
+endif()
+
 if(WITH_IMAGE_OPENEXR)
        add_definitions(-DWITH_OPENEXR)
 endif()
index d865912f5e0dc4fcfaf2d699e769548ec72964da..52b8b535038e6df08b571e6eb2949044e2ba7c2a 100644 (file)
@@ -27,6 +27,10 @@ if env['WITH_BF_PYTHON']:
     if env['BF_DEBUG']:
         defs.append('DEBUG')
 
+if env['WITH_BF_ELTOPO']:
+    incs += ' ../../../extern/eltopo'
+    defs.append('WITH_ELTOPO')
+        
 if env['WITH_BF_QUICKTIME']:
     incs += ' ../quicktime'
 
index 7d3219d917e3879019187be57402fc2ea1bad35b..d9c98bc0200af2a4e782ec1b32add26497d7370e 100644 (file)
@@ -1772,11 +1772,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                        modifier_setError(md, "Modifier requires original data, bad stack position.");
                        continue;
                }
-               if(sculpt_mode && (!has_multires || multires_applied))
-                       if(mti->type != eModifierTypeType_OnlyDeform || multires_applied) {
+               if(sculpt_mode && (!has_multires || multires_applied)) {
+                       int unsupported= 0;
+
+                       if(scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
+                               unsupported|= mti->type != eModifierTypeType_OnlyDeform;
+
+                       unsupported|= md->type == eModifierType_Multires && ((MultiresModifierData*)md)->sculptlvl==0;
+                       unsupported|= multires_applied;
+
+                       if(unsupported) {
                                modifier_setError(md, "Not supported in sculpt mode.");
                                continue;
                        }
+               }
                if(needMapping && !modifier_supportsMapping(md)) continue;
                if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
 
@@ -1815,7 +1824,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                         * to avoid giving bogus normals to the next modifier see: [#23673] */
                        if(isPrevDeform &&  mti->dependsOnNormals && mti->dependsOnNormals(md)) {
                                /* XXX, this covers bug #23673, but we may need normal calc for other types */
-                               if(dm->type == DM_TYPE_CDDM) {
+                               if(dm && dm->type == DM_TYPE_CDDM) {
                                        CDDM_apply_vert_coords(dm, deformedVerts);
                                        CDDM_calc_normals(dm);
                                }
index ce6a95430e3005025cd3407009d4d0086db3da4c..75c6303d800dddbdfd81b7bfd91c4f85a6cba1ff 100644 (file)
@@ -619,24 +619,14 @@ void BKE_reset_undo(void)
 /* based on index nr it does a restore */
 void BKE_undo_number(bContext *C, int nr)
 {
-       UndoElem *uel;
-       int a=1;
-       
-       for(uel= undobase.first; uel; uel= uel->next, a++) {
-               if(a==nr) break;
-       }
-       curundo= uel;
+       curundo= BLI_findlink(&undobase, nr - 1);
        BKE_undo_step(C, 0);
 }
 
 /* go back to the last occurance of name in stack */
 void BKE_undo_name(bContext *C, const char *name)
 {
-       UndoElem *uel;
-
-       for(uel= undobase.last; uel; uel= uel->prev)
-               if(strcmp(name, uel->name)==0)
-                       break;
+       UndoElem *uel= BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
 
        if(uel && uel->prev) {
                curundo= uel->prev;
@@ -648,12 +638,7 @@ void BKE_undo_name(bContext *C, const char *name)
 int BKE_undo_valid(const char *name)
 {
        if(name) {
-               UndoElem *uel;
-               
-               for(uel= undobase.last; uel; uel= uel->prev)
-                       if(strcmp(name, uel->name)==0)
-                               break;
-               
+               UndoElem *uel= BLI_rfindstring(&undobase, name, offsetof(UndoElem, name));
                return uel && uel->prev;
        }
        
index 8bd650b1a423e25a41f293ffb348b72b710d4fc9..72ee9b55800ff13cc029f2d7d2982e16036fde3f 100644 (file)
@@ -231,19 +231,21 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
           this derivedmesh is just original mesh. it's the multires subsurf dm
           that this is actually for, to support a pbvh on a modified mesh */
        if(!cddm->pbvh && ob->type == OB_MESH) {
+               SculptSession *ss= ob->sculpt;
                Mesh *me= ob->data;
                cddm->pbvh = BLI_pbvh_new();
                cddm->pbvh_draw = can_pbvh_draw(ob, dm);
                BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
                                   me->totface, me->totvert);
 
-               if(ob->sculpt->modifiers_active) {
+               if(ss->modifiers_active && ob->derivedDeform) {
+                       DerivedMesh *deformdm= ob->derivedDeform;
                        float (*vertCos)[3];
                        int totvert;
 
-                       totvert= dm->getNumVerts(dm);
+                       totvert= deformdm->getNumVerts(deformdm);
                        vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
-                       dm->getVertCos(dm, vertCos);
+                       deformdm->getVertCos(deformdm, vertCos);
                        BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
                        MEM_freeN(vertCos);
                }
@@ -594,26 +596,26 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha
                                glBegin(glmode = new_glmode);
                        }
                                
-                       glColor3ub(cp1[0], cp1[1], cp1[2]);
+                       glColor3ubv(cp1+0);
                        glVertex3fv(mvert[mface->v1].co);
-                       glColor3ub(cp1[4], cp1[5], cp1[6]);
+                       glColor3ubv(cp1+4);
                        glVertex3fv(mvert[mface->v2].co);
-                       glColor3ub(cp1[8], cp1[9], cp1[10]);
+                       glColor3ubv(cp1+8);
                        glVertex3fv(mvert[mface->v3].co);
                        if(mface->v4) {
-                               glColor3ub(cp1[12], cp1[13], cp1[14]);
+                               glColor3ubv(cp1+12);
                                glVertex3fv(mvert[mface->v4].co);
                        }
                                
                        if(useTwoSided) {
-                               glColor3ub(cp2[8], cp2[9], cp2[10]);
+                               glColor3ubv(cp2+8);
                                glVertex3fv(mvert[mface->v3].co );
-                               glColor3ub(cp2[4], cp2[5], cp2[6]);
+                               glColor3ubv(cp2+4);
                                glVertex3fv(mvert[mface->v2].co );
-                               glColor3ub(cp2[0], cp2[1], cp2[2]);
+                               glColor3ubv(cp2+0);
                                glVertex3fv(mvert[mface->v1].co );
                                if(mface->v4) {
-                                       glColor3ub(cp2[12], cp2[13], cp2[14]);
+                                       glColor3ubv(cp2+12);
                                        glVertex3fv(mvert[mface->v4].co );
                                }
                        }
index 5eccf7242561e4b6a8069165c400b0a833f2b0be..ea055e90b45477df459c03ebc9faf66f51c2fbc9 100644 (file)
@@ -919,7 +919,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
        if(!first)
                implicit_set_positions(clmd);
 
-       clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon );
+       clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) );
        
        for(i = 0; i < dm->getNumVerts(dm); i++)
        {
index ebdbbfcf7b4a5d1d1ed0586b7d54ada3b0320600..e2a1b0dfb33e1277b3c10ae913ea75d57dd18bf4 100644 (file)
@@ -48,6 +48,9 @@
 #include "BLI_math.h"
 #include "BLI_edgehash.h"
 #include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+#include "BLI_memarena.h"
+#include "BLI_rand.h"
 
 #include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BLI_kdopbvh.h"
 #include "BKE_collision.h"
 
+#ifdef WITH_ELTOPO
+#include "eltopo-capi.h"
+#endif
+
 
 /***********************************
 Collision modifier code start
@@ -486,7 +493,7 @@ DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float
        VECADDMUL ( to, v3, w3 );
 }
 
-
+#ifndef WITH_ELTOPO
 static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
 {
        int result = 0;
@@ -601,12 +608,799 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
        }
        return result;
 }
+#endif /* !WITH_ELTOPO */
+
+#ifdef WITH_ELTOPO
+typedef struct edgepairkey {
+       int a1, a2, b1, b2;
+} edgepairkey;
+
+unsigned int edgepair_hash(void *vkey)
+{
+       edgepairkey *key = vkey;
+       int keys[4] = {key->a1, key->a2, key->b1, key->b2};
+       int i, j;
+       
+       for (i=0; i<4; i++) {
+               for (j=0; j<3; j++) {
+                       if (keys[j] >= keys[j+1]) {
+                               SWAP(int, keys[j], keys[j+1]);
+                       }
+               }
+       }
+       
+       return keys[0]*101 + keys[1]*72 + keys[2]*53 + keys[3]*34;
+}
+
+int edgepair_cmp(const void *va, const void *vb)
+{
+       edgepairkey *a = va, *b = vb;
+       int keysa[4] = {a->a1, a->a2, a->b1, a->b2};
+       int keysb[4] = {b->a1, b->a2, b->b1, b->b2};
+       int i;
+       
+       for (i=0; i<4; i++) {
+               int j, ok=0;
+               for (j=0; j<4; j++) {
+                       if (keysa[i] == keysa[j]) {
+                               ok = 1;
+                               break;
+                       }
+               }
+               if (!ok)
+                       return -1;
+       }
+       
+       return 0;
+}
+
+static void get_edgepairkey(edgepairkey *key, int a1, int a2, int b1, int b2)
+{
+       key->a1 = a1;
+       key->a2 = a2;
+       key->b1 = b1;
+       key->b2 = b2;
+}
+
+/*an immense amount of duplication goes on here. . .a major performance hit, I'm sure*/
+static CollPair* cloth_edge_collision ( ModifierData *md1, ModifierData *md2, 
+                                                                               BVHTreeOverlap *overlap, CollPair *collpair,
+                                                                               GHash *visithash, MemArena *arena)
+{
+       ClothModifierData *clmd = ( ClothModifierData * ) md1;
+       CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
+       MFace *face1=NULL, *face2 = NULL;
+       ClothVertex *verts1 = clmd->clothObject->verts;
+       double distance = 0;
+       edgepairkey *key, tstkey;
+       float epsilon1 = clmd->coll_parms->epsilon;
+       float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+       float no[3], uv[3], t, relnor;
+       int i, i1, i2, i3, i4, i5, i6;
+       Cloth *cloth = clmd->clothObject;
+       float n1[3], n2[3], off[3], v1[2][3], v2[2][3], v3[2][3], v4[2][3], v5[2][3], v6[2][3];
+       void **verts[] = {v1, v2, v3, v4, v5, v6};
+       int j, ret, bp1, bp2, bp3, ap1, ap2, ap3, table[6];
+       
+       face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
+       face2 = & ( collmd->mfaces[overlap->indexB] );
+
+       // check all 4 possible collisions
+       for ( i = 0; i < 4; i++ )
+       {
+               if ( i == 0 )
+               {
+                       // fill faceA
+                       ap1 = face1->v1;
+                       ap2 = face1->v2;
+                       ap3 = face1->v3;
+
+                       // fill faceB
+                       bp1 = face2->v1;
+                       bp2 = face2->v2;
+                       bp3 = face2->v3;
+               }
+               else if ( i == 1 )
+               {
+                       if ( face1->v4 )
+                       {
+                               // fill faceA
+                               ap1 = face1->v1;
+                               ap2 = face1->v3;
+                               ap3 = face1->v4;
+
+                               // fill faceB
+                               bp1 = face2->v1;
+                               bp2 = face2->v2;
+                               bp3 = face2->v3;
+                       }
+                       else {
+                               continue;
+                       }
+               }
+               if ( i == 2 )
+               {
+                       if ( face2->v4 )
+                       {
+                               // fill faceA
+                               ap1 = face1->v1;
+                               ap2 = face1->v2;
+                               ap3 = face1->v3;
+
+                               // fill faceB
+                               bp1 = face2->v1;
+                               bp2 = face2->v3;
+                               bp3 = face2->v4;
+                       }
+                       else {
+                               continue;
+                       }
+               }
+               else if ( i == 3 )
+               {
+                       if ( face1->v4 && face2->v4 )
+                       {
+                               // fill faceA
+                               ap1 = face1->v1;
+                               ap2 = face1->v3;
+                               ap3 = face1->v4;
+
+                               // fill faceB
+                               bp1 = face2->v1;
+                               bp2 = face2->v3;
+                               bp3 = face2->v4;
+                       }
+                       else {
+                               continue;
+                       }
+               }
+               
+               copy_v3_v3(v1[0], cloth->verts[ap1].txold); 
+               copy_v3_v3(v1[1], cloth->verts[ap1].tx);
+               copy_v3_v3(v2[0], cloth->verts[ap2].txold);
+               copy_v3_v3(v2[1], cloth->verts[ap2].tx);
+               copy_v3_v3(v3[0], cloth->verts[ap3].txold);
+               copy_v3_v3(v3[1], cloth->verts[ap3].tx);
+               
+               copy_v3_v3(v4[0], collmd->current_x[bp1].co);
+               copy_v3_v3(v4[1], collmd->current_xnew[bp1].co);
+               copy_v3_v3(v5[0], collmd->current_x[bp2].co);
+               copy_v3_v3(v5[1], collmd->current_xnew[bp2].co);
+               copy_v3_v3(v6[0], collmd->current_x[bp3].co);
+               copy_v3_v3(v6[1], collmd->current_xnew[bp3].co);
+               
+               normal_tri_v3(n2, v4[1], v5[1], v6[1]);
+
+               /*offset new positions a bit, to account for margins*/
+               i1 = ap1; i2 = ap2; i3 = ap3;
+               i4 = bp1; i5 = bp2; i6 = bp3;
+
+               for (j=0; j<3; j++) {
+                       int collp1, collp2, k, j2 = (j+1)%3;
+                       
+                       table[0] = ap1; table[1] = ap2; table[2] = ap3;
+                       table[3] = bp1; table[4] = bp2; table[5] = bp3;
+                       for (k=0; k<3; k++) {
+                               float p1[3], p2[3];
+                               int k2 = (k+1)%3;
+                               
+                               get_edgepairkey(&tstkey, table[j], table[j2], table[k+3], table[k2+3]);
+                               //if (BLI_ghash_haskey(visithash, &tstkey))
+                               //      continue;
+                               
+                               key = BLI_memarena_alloc(arena, sizeof(edgepairkey));
+                               *key = tstkey;
+                               BLI_ghash_insert(visithash, key, NULL);
+
+                               sub_v3_v3v3(p1, verts[j], verts[j2]);
+                               sub_v3_v3v3(p2, verts[k+3], verts[k2+3]);
+                               
+                               cross_v3_v3v3(off, p1, p2);
+                               normalize_v3(off);
+
+                               if (dot_v3v3(n2, off) < 0.0)
+                                       negate_v3(off);
+                               
+                               mul_v3_fl(off,  epsilon1 + epsilon2 + ALMOST_ZERO);
+                               copy_v3_v3(p1, verts[k+3]);
+                               copy_v3_v3(p2, verts[k2+3]);
+                               add_v3_v3(p1, off);
+                               add_v3_v3(p2, off);
+                               
+                               ret = eltopo_line_line_moving_isect_v3v3_f(verts[j], table[j], verts[j2], table[j2], 
+                                                                                                                  p1, table[k+3], p2, table[k2+3], 
+                                                                                                                  no, uv, &t, &relnor);
+                               /*cloth vert versus coll face*/
+                               if (ret) {
+                                       collpair->ap1 = table[j]; collpair->ap2 = table[j2]; 
+                                       collpair->bp1 = table[k+3]; collpair->bp2 = table[k2+3];
+                                       
+                                       /*I'm not sure if this is correct, but hopefully it's 
+                                         better then simply ignoring back edges*/
+                                       if (dot_v3v3(n2, no) < 0.0) {
+                                               negate_v3(no);
+                                       }
+                                       
+                                       copy_v3_v3(collpair->normal, no);
+                                       mul_v3_v3fl(collpair->vector, collpair->normal, relnor);
+                                       collpair->distance = relnor;
+                                       collpair->time = t;
+                                       
+                                       copy_v2_v2(collpair->bary, uv);
+                                       
+                                       collpair->flag = COLLISION_IS_EDGES;
+                                       collpair++;
+                               }
+                       }
+               }
+       }
+       
+       return collpair;
+}
+
+static int cloth_edge_collision_response_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+{
+       int result = 0;
+       Cloth *cloth1;
+       float w1, w2;
+       float v1[3], v2[3], relativeVelocity[3];
+       float magrelVel, pimpulse[3];
+
+       cloth1 = clmd->clothObject;
+
+       for ( ; collpair != collision_end; collpair++ )
+       {
+               if (!(collpair->flag & COLLISION_IS_EDGES))
+                       continue;
+               
+               // was: txold
+               w1 = collpair->bary[0]; w2 = collpair->bary[1];                 
+               
+               // Calculate relative "velocity".
+               VECADDFAC(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, w1);
+               VECADDFAC(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, w2);
+               
+               VECSUB ( relativeVelocity, v2, v1);
+               
+               // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+               magrelVel = INPR ( relativeVelocity, collpair->normal );
+
+               // If v_n_mag < 0 the edges are approaching each other.
+               if ( magrelVel > ALMOST_ZERO )
+               {
+                       // Calculate Impulse magnitude to stop all motion in normal direction.
+                       float magtangent = 0, repulse = 0, d = 0;
+                       double impulse = 0.0;
+                       float vrel_t_pre[3];
+                       float temp[3], spf;
+                       
+                       zero_v3(pimpulse);
+                       
+                       // calculate tangential velocity
+                       VECCOPY ( temp, collpair->normal );
+                       mul_v3_fl( temp, magrelVel );
+                       VECSUB ( vrel_t_pre, relativeVelocity, temp );
+
+                       // Decrease in magnitude of relative tangential velocity due to coulomb friction
+                       // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+                       magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
+
+                       // Apply friction impulse.
+                       if ( magtangent > ALMOST_ZERO )
+                       {
+                               normalize_v3( vrel_t_pre );
+
+                               impulse = magtangent; 
+                               VECADDMUL ( pimpulse, vrel_t_pre, impulse);
+                       }
+
+                       // Apply velocity stopping impulse
+                       // I_c = m * v_N / 2.0
+                       // no 2.0 * magrelVel normally, but looks nicer DG
+                       impulse =  magrelVel;
+                       
+                       mul_v3_fl(collpair->normal, 0.5);
+                       VECADDMUL ( pimpulse, collpair->normal, impulse);
+
+                       // Apply repulse impulse if distance too short
+                       // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+                       spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+
+                       d = collpair->distance;
+                       if ( ( magrelVel < 0.1*d*spf && ( d > ALMOST_ZERO ) ) )
+                       {
+                               repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
+
+                               // stay on the safe side and clamp repulse
+                               if ( impulse > ALMOST_ZERO )
+                                       repulse = MIN2 ( repulse, 5.0*impulse );
+                               repulse = MAX2 ( impulse, repulse );
+
+                               impulse = repulse / ( 5.0 ); // original 2.0 / 0.25
+                               VECADDMUL ( pimpulse, collpair->normal, impulse);
+                       }
+                       
+                       w2 = 1.0f-w1;
+                       if (w1 < 0.5)
+                               w1 *= 2.0;
+                       else
+                               w2 *= 2.0;
+                       
+                       VECADDFAC(cloth1->verts[collpair->ap1].impulse, cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0);
+                       VECADDFAC(cloth1->verts[collpair->ap2].impulse, cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0);
+                       
+                       cloth1->verts[collpair->ap1].impulse_count++;
+                       cloth1->verts[collpair->ap2].impulse_count++;
+                       
+                       result = 1;
+               }
+       } 
+       
+       return result;
+}
+
+static int cloth_collision_response_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
+{
+       int result = 0;
+       Cloth *cloth1;
+       float w1, w2, w3, u1, u2, u3;
+       float v1[3], v2[3], relativeVelocity[3];
+       float magrelVel;
+       float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+       
+       cloth1 = clmd->clothObject;
+
+       for ( ; collpair != collision_end; collpair++ )
+       {
+               if (collpair->flag & COLLISION_IS_EDGES)
+                       continue;
+               
+               if ( collpair->flag & COLLISION_USE_COLLFACE ) {
+                       // was: txold
+                       w1 = collpair->bary[0]; w2 = collpair->bary[1]; w3 = collpair->bary[2];                 
+
+                       // Calculate relative "velocity".
+                       collision_interpolateOnTriangle ( v1, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, w1, w2, w3);
+                       
+                       VECSUB ( relativeVelocity, v1, cloth1->verts[collpair->collp].tv);
+                       
+                       // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+                       magrelVel = INPR ( relativeVelocity, collpair->normal );
+       
+                       // If v_n_mag < 0 the edges are approaching each other.
+                       if ( magrelVel > ALMOST_ZERO )
+                       {
+                               // Calculate Impulse magnitude to stop all motion in normal direction.
+                               float magtangent = 0, repulse = 0, d = 0;
+                               double impulse = 0.0;
+                               float vrel_t_pre[3];
+                               float temp[3], spf;
+       
+                               // calculate tangential velocity
+                               VECCOPY ( temp, collpair->normal );
+                               mul_v3_fl( temp, magrelVel );
+                               VECSUB ( vrel_t_pre, relativeVelocity, temp );
+       
+                               // Decrease in magnitude of relative tangential velocity due to coulomb friction
+                               // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+                               magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
+       
+                               // Apply friction impulse.
+                               if ( magtangent > ALMOST_ZERO )
+                               {
+                                       normalize_v3( vrel_t_pre );
+       
+                                       impulse = magtangent; // 2.0 * 
+                                       VECADDMUL ( cloth1->verts[collpair->collp].impulse, vrel_t_pre, impulse);
+                               }
+       
+                               // Apply velocity stopping impulse
+                               // I_c = m * v_N / 2.0
+                               // no 2.0 * magrelVel normally, but looks nicer DG
+                               impulse =  magrelVel/2.0;
+       
+                               VECADDMUL ( cloth1->verts[collpair->collp].impulse, collpair->normal, impulse);
+                               cloth1->verts[collpair->collp].impulse_count++;
+       
+                               // Apply repulse impulse if distance too short
+                               // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+                               spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+       
+                               d = -collpair->distance;
+                               if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) )
+                               {
+                                       repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
+       
+                                       // stay on the safe side and clamp repulse
+                                       if ( impulse > ALMOST_ZERO )
+                                               repulse = MIN2 ( repulse, 5.0*impulse );
+                                       repulse = MAX2 ( impulse, repulse );
+       
+                                       impulse = repulse / ( 5.0 ); // original 2.0 / 0.25
+                                       VECADDMUL ( cloth1->verts[collpair->collp].impulse, collpair->normal, impulse);
+                               }
+       
+                               result = 1;
+                       }
+               } else {        
+                       w1 = collpair->bary[0]; w2 = collpair->bary[1]; w3 = collpair->bary[2];                 
+
+                       // Calculate relative "velocity".
+                       collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 );
+       
+                       VECSUB ( relativeVelocity, collmd->current_v[collpair->collp].co, v1);
+                       
+                       // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal').
+                       magrelVel = INPR ( relativeVelocity, collpair->normal );
+       
+                       // If v_n_mag < 0 the edges are approaching each other.
+                       if ( magrelVel > ALMOST_ZERO )
+                       {
+                               // Calculate Impulse magnitude to stop all motion in normal direction.
+                               float magtangent = 0, repulse = 0, d = 0;
+                               double impulse = 0.0;
+                               float vrel_t_pre[3], pimpulse[3] = {0.0f, 0.0f, 0.0f};
+                               float temp[3], spf;
+       
+                               // calculate tangential velocity
+                               VECCOPY ( temp, collpair->normal );
+                               mul_v3_fl( temp, magrelVel );
+                               VECSUB ( vrel_t_pre, relativeVelocity, temp );
+       
+                               // Decrease in magnitude of relative tangential velocity due to coulomb friction
+                               // in original formula "magrelVel" should be the "change of relative velocity in normal direction"
+                               magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) );
+       
+                               // Apply friction impulse.
+                               if ( magtangent > ALMOST_ZERO )
+                               {
+                                       normalize_v3( vrel_t_pre );
+       
+                                       impulse = magtangent; // 2.0 * 
+                                       VECADDMUL ( pimpulse, vrel_t_pre, impulse);
+                               }
+       
+                               // Apply velocity stopping impulse
+                               // I_c = m * v_N / 2.0
+                               // no 2.0 * magrelVel normally, but looks nicer DG
+                               impulse =  magrelVel/2.0;
+       
+                               VECADDMUL ( pimpulse, collpair->normal, impulse);
+       
+                               // Apply repulse impulse if distance too short
+                               // I_r = -min(dt*kd, m(0,1d/dt - v_n))
+                               spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale;
+       
+                               d = -collpair->distance;
+                               if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) )
+                               {
+                                       repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel );
+       
+                                       // stay on the safe side and clamp repulse
+                                       if ( impulse > ALMOST_ZERO )
+                                               repulse = MIN2 ( repulse, 5.0*impulse );
+                                       repulse = MAX2 ( impulse, repulse );
+       
+                                       impulse = repulse / ( 2.0 ); // original 2.0 / 0.25
+                                       VECADDMUL ( pimpulse, collpair->normal, impulse);
+                               }
+                               
+                               if (w1 < 0.5) w1 *= 2.0;
+                               if (w2 < 0.5) w2 *= 2.0;
+                               if (w3 < 0.5) w3 *= 2.0;
+                               
+                               VECADDMUL(cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0);
+                               VECADDMUL(cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0);
+                               VECADDMUL(cloth1->verts[collpair->ap3].impulse, pimpulse, w3*2.0);;
+                               cloth1->verts[collpair->ap1].impulse_count++;
+                               cloth1->verts[collpair->ap2].impulse_count++;
+                               cloth1->verts[collpair->ap3].impulse_count++;
+                               
+                               result = 1;
+                       }
+               }
+       } 
+       
+       return result;
+}
+
+
+typedef struct tripairkey {
+       int p, a1, a2, a3;
+} tripairkey;
+
+unsigned int tripair_hash(void *vkey)
+{
+       tripairkey *key = vkey;
+       int keys[4] = {key->p, key->a1, key->a2, key->a3};
+       int i, j;
+       
+       for (i=0; i<4; i++) {
+               for (j=0; j<3; j++) {
+                       if (keys[j] >= keys[j+1]) {
+                               SWAP(int, keys[j], keys[j+1]);
+                       }
+               }
+       }
+       
+       return keys[0]*101 + keys[1]*72 + keys[2]*53 + keys[3]*34;
+}
+
+int tripair_cmp(const void *va, const void *vb)
+{
+       tripairkey *a = va, *b = vb;
+       int keysa[4] = {a->p, a->a1, a->a2, a->a3};
+       int keysb[4] = {b->p, b->a1, b->a2, b->a3};
+       int i;
+       
+       for (i=0; i<4; i++) {
+               int j, ok=0;
+               for (j=0; j<4; j++) {
+                       if (keysa[i] == keysa[j]) {
+                               ok = 1;
+                               break;
+                       }
+               }
+               if (!ok)
+                       return -1;
+       }
+       
+       return 0;
+}
+
+static void get_tripairkey(tripairkey *key, int p, int a1, int a2, int a3)
+{
+       key->a1 = a1;
+       key->a2 = a2;
+       key->a3 = a3;
+       key->p = p;
+}
+
+static int checkvisit(MemArena *arena, GHash *gh, int p, int a1, int a2, int a3)
+{
+       tripairkey key, *key2;
+       
+       get_tripairkey(&key, p, a1, a2, a3);
+       if (BLI_ghash_haskey(gh, &key))
+               return 1;
+       
+       key2 = BLI_memarena_alloc(arena, sizeof(*key2));
+       *key2 = key;
+       BLI_ghash_insert(gh, key2, NULL);
+       
+       return 0;
+}
+
+int cloth_point_tri_moving_v3v3_f(float v1[2][3], int i1, float v2[2][3], int i2,
+                                   float v3[2][3],  int i3, float v4[2][3], int i4,
+                                   float normal[3], float bary[3], float *t, 
+                                                                  float *relnor, GHash *gh, MemArena *arena)
+{
+       if (checkvisit(arena, gh, i1, i2, i3, i4))
+               return 0;
+       
+       return eltopo_point_tri_moving_v3v3_f(v1, i1, v2, i2, v3, i3, v4, i4, normal, bary, t, relnor);
+}
+
+static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, 
+                                                                  CollPair *collpair, double dt, GHash *gh, MemArena *arena)
+{
+       ClothModifierData *clmd = ( ClothModifierData * ) md1;
+       CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
+       MFace *face1=NULL, *face2 = NULL;
+       ClothVertex *verts1 = clmd->clothObject->verts;
+       double distance = 0;
+       float epsilon1 = clmd->coll_parms->epsilon;
+       float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+       float no[3], uv[3], t, relnor;
+       int i, i1, i2, i3, i4, i5, i6;
+       Cloth *cloth = clmd->clothObject;
+       float n1[3], sdis, p[3], l, n2[3], off[3], v1[2][3], v2[2][3], v3[2][3], v4[2][3], v5[2][3], v6[2][3];
+       int j, ret, bp1, bp2, bp3, ap1, ap2, ap3;
+       
+       face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
+       face2 = & ( collmd->mfaces[overlap->indexB] );
+
+       // check all 4 possible collisions
+       for ( i = 0; i < 4; i++ )
+       {
+               if ( i == 0 )
+               {
+                       // fill faceA
+                       ap1 = face1->v1;
+                       ap2 = face1->v2;
+                       ap3 = face1->v3;
+
+                       // fill faceB
+                       bp1 = face2->v1;
+                       bp2 = face2->v2;
+                       bp3 = face2->v3;
+               }
+               else if ( i == 1 )
+               {
+                       if ( face1->v4 )
+                       {
+                               // fill faceA
+                               ap1 = face1->v1;
+                               ap2 = face1->v3;
+                               ap3 = face1->v4;
+
+                               // fill faceB
+                               bp1 = face2->v1;
+                               bp2 = face2->v2;
+                               bp3 = face2->v3;
+                       }
+                       else {
+                               continue;
+                       }
+               }
+               if ( i == 2 )
+               {
+                       if ( face2->v4 )
+                       {
+                               // fill faceA
+                               ap1 = face1->v1;
+                               ap2 = face1->v2;
+                               ap3 = face1->v3;
+
+                               // fill faceB
+                               bp1 = face2->v1;
+                               bp2 = face2->v3;
+                               bp3 = face2->v4;
+                       }
+                       else {
+                               continue;
+                       }
+               }
+               else if ( i == 3 )
+               {
+                       if ( face1->v4 && face2->v4 )
+                       {
+                               // fill faceA
+                               ap1 = face1->v1;
+                               ap2 = face1->v3;
+                               ap3 = face1->v4;
+
+                               // fill faceB
+                               bp1 = face2->v1;
+                               bp2 = face2->v3;
+                               bp3 = face2->v4;
+                       }
+                       else {
+                               continue;
+                       }
+               }
+               
+               copy_v3_v3(v1[0], cloth->verts[ap1].txold); 
+               copy_v3_v3(v1[1], cloth->verts[ap1].tx);
+               copy_v3_v3(v2[0], cloth->verts[ap2].txold);
+               copy_v3_v3(v2[1], cloth->verts[ap2].tx);
+               copy_v3_v3(v3[0], cloth->verts[ap3].txold);
+               copy_v3_v3(v3[1], cloth->verts[ap3].tx);
+               
+               copy_v3_v3(v4[0], collmd->current_x[bp1].co);
+               copy_v3_v3(v4[1], collmd->current_xnew[bp1].co);
+               copy_v3_v3(v5[0], collmd->current_x[bp2].co);
+               copy_v3_v3(v5[1], collmd->current_xnew[bp2].co);
+               copy_v3_v3(v6[0], collmd->current_x[bp3].co);
+               copy_v3_v3(v6[1], collmd->current_xnew[bp3].co);
+               
+               normal_tri_v3(n2, v4[1], v5[1], v6[1]);
+               
+               sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON;
+
+               /*apply a repulsion force, to help the solver along*/
+               copy_v3_v3(off, n2);
+               negate_v3(off);
+               if (isect_ray_plane_v3(v1[1], off, v4[1], v5[1], v6[1], &l, 0)) {
+                       if (l >= 0.0 && l < sdis) {
+                               mul_v3_fl(off, (l-sdis)*cloth->verts[ap1].mass*dt*clmd->coll_parms->repel_force*0.1);
+
+                               add_v3_v3(cloth->verts[ap1].tv, off);
+                               add_v3_v3(cloth->verts[ap2].tv, off);
+                               add_v3_v3(cloth->verts[ap3].tv, off);
+                       }
+               }
+
+               /*offset new positions a bit, to account for margins*/
+               copy_v3_v3(off, n2);
+               mul_v3_fl(off,  epsilon1 + epsilon2 + ALMOST_ZERO);
+               add_v3_v3(v4[1], off); add_v3_v3(v5[1], off); add_v3_v3(v6[1], off);
+               
+               i1 = ap1; i2 = ap2; i3 = ap3;
+               i4 = bp1+cloth->numverts; i5 = bp2+cloth->numverts; i6 = bp3+cloth->numverts;
+               
+               for (j=0; j<6; j++) {
+                       int collp;
+
+                       switch (j) {
+                       case 0:
+                               ret = cloth_point_tri_moving_v3v3_f(v1, i1, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena);
+                               collp = ap1;
+                               break;
+                       case 1:
+                               collp = ap2;
+                               ret = cloth_point_tri_moving_v3v3_f(v2, i2, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena);
+                               break;
+                       case 2:
+                               collp = ap3;
+                               ret = cloth_point_tri_moving_v3v3_f(v3, i3, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena);
+                               break;
+                       case 3:
+                               collp = bp1;
+                               ret = cloth_point_tri_moving_v3v3_f(v4, i4, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena);
+                               break;
+                       case 4:
+                               collp = bp2;                            
+                               ret = cloth_point_tri_moving_v3v3_f(v5, i5, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena);
+                               break;
+                       case 5:
+                               collp = bp3;
+                               ret = cloth_point_tri_moving_v3v3_f(v6, i6, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena);
+                               break;
+                       }
+                       
+                       /*cloth vert versus coll face*/
+                       if (ret && j < 3) {
+                               collpair->bp1 = bp1; collpair->bp2 = bp2; collpair->bp3 = bp3;
+                               collpair->collp = collp;
+                               
+                               copy_v3_v3(collpair->normal, no);
+                               mul_v3_v3fl(collpair->vector, collpair->normal, relnor);
+                               collpair->distance = relnor;
+                               collpair->time = t;
+                               
+                               copy_v3_v3(collpair->bary, uv);
+                               
+                               collpair->flag = COLLISION_USE_COLLFACE;
+                               collpair++;
+                       } else if (ret && j >= 3) { /*coll vert versus cloth face*/
+                               collpair->ap1 = ap1; collpair->ap2 = ap2; collpair->ap3 = ap3;
+                               collpair->collp = collp;
+                               
+                               copy_v3_v3(collpair->normal, no);
+                               mul_v3_v3fl(collpair->vector, collpair->normal, relnor);
+                               collpair->distance = relnor;
+                               collpair->time = t;
+                               
+                               copy_v3_v3(collpair->bary, uv);
+
+                               collpair->flag = 0;
+                               collpair++;
+                       }
+               }
+       }
+       
+       return collpair;
+}
+
+static void machine_epsilon_offset(Cloth *cloth) {
+       ClothVertex *cv;
+       int i, j;
+       
+       cv = cloth->verts;
+       for (i=0; i<cloth->numverts; i++, cv++) {
+               /*aggrevatingly enough, it's necassary to offset the coordinates
+                by a multiple of the 32-bit floating point epsilon when switching
+                into doubles*/
+               #define RNDSIGN (float)(-1*(BLI_rand()%2==0)|1)
+               for (j=0; j<3; j++) {
+                       cv->tx[j] += FLT_EPSILON*30.0f*RNDSIGN;
+                       cv->txold[j] += FLT_EPSILON*30.0f*RNDSIGN;
+                       cv->tv[j] += FLT_EPSILON*30.0f*RNDSIGN;
+               }               
+       }
+}
+
+#else /* !WITH_ELTOPO */
 
 //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
-static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair )
+static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, 
+       BVHTreeOverlap *overlap, CollPair *collpair, float dt )
 {
        ClothModifierData *clmd = ( ClothModifierData * ) md1;
        CollisionModifierData *collmd = ( CollisionModifierData * ) md2;
+       Cloth *cloth = clmd->clothObject;
        MFace *face1=NULL, *face2 = NULL;
 #ifdef USE_BULLET
        ClothVertex *verts1 = clmd->clothObject->verts;
@@ -614,6 +1408,7 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree
        double distance = 0;
        float epsilon1 = clmd->coll_parms->epsilon;
        float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree );
+       float n2[3], sdis, l;
        int i;
 
        face1 = & ( clmd->clothObject->mfaces[overlap->indexA] );
@@ -685,7 +1480,28 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree
                        else
                                break;
                }
+               
+               normal_tri_v3(n2, collmd->current_xnew[collpair->bp1].co, 
+                       collmd->current_xnew[collpair->bp2].co, 
+                       collmd->current_xnew[collpair->bp3].co);
+               
+               sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON;
+               
+               /*apply a repulsion force, to help the solver along.
+          this is kindof crude, it only tests one vert of the triangle*/
+               if (isect_ray_plane_v3(cloth->verts[collpair->ap1].tx, n2, collmd->current_xnew[collpair->bp1].co, 
+                       collmd->current_xnew[collpair->bp2].co,
+                       collmd->current_xnew[collpair->bp3].co, &l, 0))
+               {
+                       if (l >= 0.0 && l < sdis) {
+                               mul_v3_fl(n2, (l-sdis)*cloth->verts[collpair->ap1].mass*dt*clmd->coll_parms->repel_force*0.1);
 
+                               add_v3_v3(cloth->verts[collpair->ap1].tv, n2);
+                               add_v3_v3(cloth->verts[collpair->ap2].tv, n2);
+                               add_v3_v3(cloth->verts[collpair->ap3].tv, n2);
+                       }
+               }
+               
 #ifdef USE_BULLET
                // calc distance + normal
                distance = plNearestPoints (
@@ -741,6 +1557,8 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree
        }
        return collpair;
 }
+#endif /* WITH_ELTOPO */
+
 
 #if 0
 static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end )
@@ -1446,17 +2264,45 @@ void free_collider_cache(ListBase **colliders)
        }
 }
 
-static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap)
+
+static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd,
+       CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap, double dt)
 {
        int i;
+#ifdef WITH_ELTOPO
+       GHash *visithash = BLI_ghash_new(edgepair_hash, edgepair_cmp, "visthash, collision.c");
+       GHash *tri_visithash = BLI_ghash_new(tripair_hash, tripair_cmp, "tri_visthash, collision.c");
+       MemArena *arena = BLI_memarena_new(1<<16, "edge hash arena, collision.c");
+#endif
        
-       *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+       *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 64, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
        *collisions_index = *collisions;
+       
+#ifdef WITH_ELTOPO
+       machine_epsilon_offset(clmd->clothObject);
+
+       for ( i = 0; i < numresult; i++ )
+       {
+               *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd,
+                                                                                         overlap+i, *collisions_index, dt, tri_visithash, arena );
+       }
 
        for ( i = 0; i < numresult; i++ )
        {
-               *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index );
+               *collisions_index = cloth_edge_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd,
+                                                                                                  overlap+i, *collisions_index, visithash, arena );
        }
+       BLI_ghash_free(visithash, NULL, NULL);
+       BLI_ghash_free(tri_visithash, NULL, NULL);
+       BLI_memarena_free(arena);
+#else /* WITH_ELTOPO */
+       for ( i = 0; i < numresult; i++ )
+       {
+               *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd,
+                                                                                         overlap+i, *collisions_index, dt );
+       }
+#endif /* WITH_ELTOPO */
+
 }
 
 static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index)
@@ -1481,11 +2327,19 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
 
                if ( collmd->bvhtree )
                {
+#ifdef WITH_ELTOPO
+                       result += cloth_collision_response_moving(clmd, collmd, collisions, collisions_index);
+                       result += cloth_edge_collision_response_moving(clmd, collmd, collisions, collisions_index);
+#else
                        result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index );
-
+#endif
+#ifdef WITH_ELTOPO
+                       {
+#else
                        // apply impulses in parallel
                        if ( result )
                        {
+#endif
                                for ( i = 0; i < numverts; i++ )
                                {
                                        // calculate "velocities" (just xnew = xold + v; no dt in v)
@@ -1518,7 +2372,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
 
        if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh==NULL)
                return 0;
-
+       
        verts = cloth->verts;
        numfaces = cloth->numfaces;
        numverts = cloth->numverts;
@@ -1557,6 +2411,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
                                continue;
                        
                        /* move object to position (step) in time */
+                       
                        collision_move_object ( collmd, step + dt, step );
                        
                        /* search for overlapping collision pairs */
@@ -1565,7 +2420,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
                        // go to next object if no overlap is there
                        if( result && overlap ) {
                                /* check if collisions really happen (costly near check) */
-                               cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap);
+                               cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], 
+                                       &collisions_index[i], result, overlap, dt/(float)clmd->coll_parms->loop_count);
                        
                                // resolve nearby collisions
                                ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i],  collisions_index[i]);
@@ -1721,5 +2577,5 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl
        if(collobjs)
                MEM_freeN(collobjs);
 
-       return MIN2 ( ret, 1 );
+       return 1|MIN2 ( ret, 1 );
 }
index d2e48edc7ced4680606de6e37c05fea81c8a9165..d3c14a9dd12c57f3f836b4f9e94578ae98a5709d 100644 (file)
@@ -4019,7 +4019,9 @@ bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con)
  
 /* ---------- Data Management ------- */
 
-/* Free data of a specific constraint if it has any info */
+/* Free data of a specific constraint if it has any info.
+ * be sure to run BIK_clear_data() when freeing an IK constraint,
+ * unless DAG_scene_sort is called. */
 void free_constraint_data (bConstraint *con)
 {
        if (con->data) {
index 55d455bc5d3b5fe26172b0dd4d04c510d00dcc59..2aeb726f623304bff7bf1282c6b4b7dc0429502c 100644 (file)
@@ -451,7 +451,7 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
 
                C->data.recursion= 1;
 
-               entry= BLI_findstring(&C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
+               entry= BLI_rfindstring(&C->wm.store->entries, member, offsetof(bContextStoreEntry, name));
                if(entry) {
                        result->ptr= entry->ptr;
                        done= 1;
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
deleted file mode 100644 (file)
index ae77381..0000000
+++ /dev/null
@@ -1,2485 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- *
- * Contributor(s):
- * - Martin DeMello
- *   Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline
- *   Copyright (C) 2004 by Etheract Software Labs
- *
- * - Blender Foundation
- *
- * ***** END GPL LICENSE BLOCK ****
- */
-
-/** \file blender/blenkernel/intern/exotic.c
- *  \ingroup bke
- */
-
-
-#include <stddef.h>
-#include "BLI_storage.h"
-
-#include <stdlib.h>
-#include <ctype.h> /* isdigit, isspace */
-#include <math.h>
-#include <stdio.h>
-
-#include <fcntl.h>
-#include <string.h>
-#include <errno.h>
-
-#ifndef _WIN32 
-#include <unistd.h>
-#else
-#include <io.h>
-#define open _open
-#define read _read
-#define close _close
-#define write _write
-#endif
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_object_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_material_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_scene_types.h"
-
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-#include "BLI_storage.h"
-#include "BLI_utildefines.h"
-
-
-#include "BKE_blender.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
-#include "BKE_mesh.h"
-#include "BKE_library.h"
-#include "BKE_object.h"
-#include "BKE_material.h"
-#include "BKE_report.h"
-#include "BKE_exotic.h"
-#include "BKE_displist.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_curve.h"
-
-#ifdef WITH_PYTHON
-#include "BPY_extern.h"
-#endif
-
-#include "zlib.h"
-
-static int is_dxf(const char *str);
-static void dxf_read(Scene *scene, const char *filename);
-static int is_stl(const char *str);
-
-static int is_stl_ascii(const char *str)
-{      
-       FILE *fpSTL;
-       char buffer[1000];
-       int  numread, i;
-
-       fpSTL = fopen(str, "rb");
-       if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 )
-         { fclose(fpSTL); return 0; }
-
-       for (i=0; i < numread; ++i) {
-         /* if bit 8 is set we assume binary */
-         if (buffer[i] & 0x80)
-               { fclose(fpSTL); return 0; }
-       }
-
-       buffer[5] = '\0';
-       if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) ) 
-         { fclose(fpSTL); return 0; }
-
-       fclose(fpSTL);
-       
-       return 1;
-}
-
-static int is_stl(const char *str)
-{
-       int i;
-       i = strlen(str) - 3;
-       if ( (str[i] !='s') && (str[i] !='S'))
-               return 0;
-       i++;
-       if ( (str[i] !='t') && (str[i] !='T'))
-               return 0;
-       i++;
-       if ( (str[i] !='l') && (str[i] !='L'))
-               return 0;
-
-       return 1;
-}
-
-#define READSTLVERT {                                             \
-       if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) {      \
-               char error_msg[255];                                \
-               MEM_freeN(vertdata);                                \
-               MEM_freeN(facedata);                                \
-               fclose(fpSTL);                                      \
-               sprintf(error_msg, "Problems reading face %d!", i); \
-               return;                                             \
-       }                                                          \
-       else {                                                     \
-               if (ENDIAN_ORDER==B_ENDIAN) {                       \
-                       SWITCH_INT(mvert->co[0]);                    \
-                       SWITCH_INT(mvert->co[1]);                    \
-                       SWITCH_INT(mvert->co[2]);                    \
-               }                                                   \
-       }                                                          \
-}
-
-static void simple_vertex_normal_blend(short *no, short *ble)
-{
-       if(no[0]==0 && no[1]==0 && no[2]==0) {
-               VECCOPY(no, ble);
-       }
-       else {
-               no[0]= (2*no[0] + ble[0])/3;
-               no[1]= (2*no[1] + ble[1])/3;
-               no[2]= (2*no[2] + ble[2])/3;
-       }
-}
-
-static void mesh_add_normals_flags(Mesh *me)
-{
-       MVert *v1, *v2, *v3, *v4;
-       MFace *mface;
-       float nor[3];
-       int a;
-       short sno[3];
-       
-       mface= me->mface;
-       for(a=0; a<me->totface; a++, mface++) {
-               v1= me->mvert+mface->v1;
-               v2= me->mvert+mface->v2;
-               v3= me->mvert+mface->v3;
-               v4= me->mvert+mface->v4;
-
-               normal_tri_v3( nor,v1->co, v2->co, v3->co);
-               normal_float_to_short_v3(sno, nor);
-
-               simple_vertex_normal_blend(v1->no, sno);
-               simple_vertex_normal_blend(v2->no, sno);
-               simple_vertex_normal_blend(v3->no, sno);
-               if(mface->v4) {
-                       simple_vertex_normal_blend(v4->no, sno);
-               }
-               mface->edcode= ME_V1V2|ME_V2V3;
-       }       
-}
-
-static void read_stl_mesh_binary(Scene *scene, const char *str)
-{
-       FILE   *fpSTL;
-       Object *ob;
-       Mesh   *me;
-       MVert  *mvert, *vertdata;
-       MFace  *mface, *facedata;
-       unsigned int numfacets = 0, i, j, vertnum;
-       unsigned int maxmeshsize, nummesh, lastmeshsize;
-       unsigned int totvert, totface;
-       ReportList *reports= NULL; /* XXX */
-
-       fpSTL= fopen(str, "rb");
-       if(fpSTL==NULL) {
-               BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
-               return;
-       }
-
-       if(fseek(fpSTL, 80, SEEK_SET) != 0) {
-               BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno));
-               fclose(fpSTL);
-               return;
-       }
-
-       if(fread(&numfacets, 4*sizeof(char), 1, fpSTL) != 1) {
-               if(feof(fpSTL))
-                       BKE_reportf(reports, RPT_ERROR, "Failed reading file: premature end of file.");
-               else
-                       BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno));
-               fclose(fpSTL);
-               return;
-       }
-       if (ENDIAN_ORDER==B_ENDIAN) {
-               SWITCH_INT(numfacets);
-       }
-
-       maxmeshsize = MESH_MAX_VERTS/3;
-
-       nummesh      = (numfacets / maxmeshsize) + 1;
-       lastmeshsize = numfacets % maxmeshsize;
-
-       if (numfacets) {
-               for (j=0; j < nummesh; ++j) {
-                       /* new object */
-                       if (j == nummesh-1) {
-                               totface = lastmeshsize;
-                       }
-                       else {
-                               totface = maxmeshsize;
-                       }
-                       totvert = 3 * totface;
-       
-                       vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts");
-                       facedata = MEM_callocN(totface*sizeof(MFace), "mface");
-
-                       vertnum = 0;
-                       mvert= vertdata;
-                       mface = facedata;
-                       for (i=0; i < totface; i++) {
-                               fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */
-                               READSTLVERT;
-                               mvert++;
-                               READSTLVERT;
-                               mvert++;
-                               READSTLVERT;
-                               mvert++;
-
-                               mface->v1 = vertnum++;
-                               mface->v2 = vertnum++;
-                               mface->v3 = vertnum++;
-                               mface++;
-
-                               fseek(fpSTL, 2, SEEK_CUR);
-                       }
-
-                       ob= add_object(scene, OB_MESH);
-                       me= ob->data;
-                       me->totvert = totvert;
-                       me->totface = totface;
-                       me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN,
-                                                                                        vertdata, totvert);
-                       me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN,
-                                                                                        facedata, totface);
-
-                       mesh_add_normals_flags(me);
-                       make_edges(me, 0);
-               }
-               //XXX waitcursor(1);
-       }
-       fclose(fpSTL);
-
-}
-#undef READSTLVERT
-
-#define STLALLOCERROR { \
-       char error_msg[255]; \
-       fclose(fpSTL); \
-       sprintf(error_msg, "Can't allocate storage for %d faces!", \
-                       numtenthousand * 10000); \
-       return; \
-}
-
-#define STLBAILOUT(message) { \
-       char error_msg[255]; \
-       fclose(fpSTL); \
-       free(vertdata); \
-       sprintf(error_msg, "Line %d: %s", linenum, message); \
-       return; \
-}
-
-#define STLREADLINE { \
-       if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \
-       linenum++; \
-}
-
-#define STLREADVERT { \
-       STLREADLINE; \
-       if ( !(cp = strstr(buffer, "vertex")) && \
-                !(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \
-       vp = vertdata + 3 * totvert; \
-       if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \
-               STLBAILOUT("Bad vertex!"); \
-       ++totvert; \
-}
-static void read_stl_mesh_ascii(Scene *scene, const char *str)
-{
-       FILE   *fpSTL;
-       char   buffer[2048], *cp;
-       Object *ob;
-       Mesh   *me;
-       MVert  *mvert;
-       MFace  *mface;
-       float  *vertdata, *vp;
-       unsigned int numtenthousand, linenum;
-       unsigned int i, vertnum;
-       unsigned int totvert, totface;
-       ReportList *reports= NULL; /* XXX */
-
-       /* ASCII stl sucks ... we don't really know how many faces there
-          are until the file is done, so lets allocate faces 10000 at a time */
-
-       fpSTL= fopen(str, "r");
-       if(fpSTL==NULL) {
-               BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno));
-               return;
-       }
-       
-       /* we'll use the standard malloc/realloc for now ... 
-        * lets allocate enough storage to hold 10000 triangles,
-        * i.e. 30000 verts, i.e., 90000 floats.
-        */
-       numtenthousand = 1;
-       vertdata = malloc(numtenthousand*3*30000*sizeof(float));        // uses realloc!
-       if (!vertdata) { STLALLOCERROR; }
-
-       linenum = 1;
-       /* Get rid of the first line */
-       STLREADLINE;
-
-       totvert = 0;
-       totface = 0;
-       while(1) {
-               /* Read in the next line */
-               STLREADLINE;
-
-               /* lets check if this is the end of the file */
-               if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") ) 
-                       break;
-
-               /* Well, guess that wasn't the end, so lets make
-                * sure we have enough storage for some more faces
-                */
-               if ( (totface) && ( (totface % 10000) == 0 ) ) {
-                       float  *vertdata_old= vertdata;
-                       ++numtenthousand;
-                       vertdata = realloc(vertdata, 
-                                                          numtenthousand*3*30000*sizeof(float));
-                       if (!vertdata) {
-                               if(vertdata_old) {
-                                       free(vertdata_old);
-                               }
-                               STLALLOCERROR;
-                       }
-               }
-               
-               /* Don't read normal, but check line for proper syntax anyway
-                */
-               if ( !(cp = strstr(buffer, "facet")) && 
-                        !(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!");
-               if ( !(strstr(cp+5, "normal")) && 
-                        !(strstr(cp+5, "NORMAL")) )       STLBAILOUT("Bad normal line!");
-
-               /* Read in what should be the outer loop line 
-                */
-               STLREADLINE;
-               if ( !(cp = strstr(buffer, "outer")) &&
-                        !(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!");
-               if ( !(strstr(cp+5, "loop")) &&
-                        !(strstr(cp+5, "LOOP")) )         STLBAILOUT("Bad outer loop!");
-
-               /* Read in the face */
-               STLREADVERT;
-               STLREADVERT;
-               STLREADVERT;
-
-               /* Read in what should be the endloop line 
-                */
-               STLREADLINE;
-               if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") ) 
-                       STLBAILOUT("Bad endloop!");
-
-               /* Read in what should be the endfacet line 
-                */
-               STLREADLINE;
-               if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") ) 
-                       STLBAILOUT("Bad endfacet!");
-
-               /* Made it this far? Increment face count */
-               ++totface;
-       }
-       fclose(fpSTL);
-
-       /* OK, lets create our mesh */
-       ob = add_object(scene, OB_MESH);
-       me = ob->data;
-
-       me->totface = totface;
-       me->totvert = totvert;
-       me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC,
-                                                                        NULL, totvert);
-       me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC,
-                                                                        NULL, totface);
-
-       /* Copy vert coords and create topology */
-       mvert = me->mvert;
-       mface = me->mface;
-       vertnum = 0;
-       for (i=0; i < totface; ++i) {
-               memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
-               mface->v1 = vertnum;
-               mvert++;
-               vertnum++;
-
-               memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
-               mface->v2 = vertnum;
-               mvert++;
-               vertnum++;
-
-               memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) );
-               mface->v3 = vertnum;
-               mvert++;
-               vertnum++;
-
-               mface++;
-       }
-       free(vertdata);
-
-       mesh_add_normals_flags(me);
-       make_edges(me, 0);
-
-       //XXX waitcursor(1);
-}
-
-#undef STLALLOCERROR
-#undef STLBAILOUT
-#undef STLREADLINE
-#undef STLREADVERT
-
-/* ************************************************************ */
-
-int BKE_read_exotic(Scene *scene, const char *name)
-{
-       int len;
-       gzFile gzfile;
-       char header[7];
-       int retval;
-
-       // make sure we're not trying to read a directory....
-
-       len= strlen(name);
-       if (ELEM(name[len-1], '/', '\\')) {
-               retval= BKE_READ_EXOTIC_FAIL_PATH;
-       }
-       else {
-               gzfile = gzopen(name,"rb");
-
-               if (gzfile == NULL) {
-                       retval= BKE_READ_EXOTIC_FAIL_OPEN;
-               }
-               else {
-                       len= gzread(gzfile, header, sizeof(header));
-                       gzclose(gzfile);
-                       if (len == sizeof(header) && strncmp(header, "BLENDER", 7) == 0) {
-                               retval= BKE_READ_EXOTIC_OK_BLEND;
-                       }
-                       else {
-                               //XXX waitcursor(1);
-                               if(is_dxf(name)) {
-                                       dxf_read(scene, name);
-                                       retval= BKE_READ_EXOTIC_OK_OTHER;
-                               }
-                               else if(is_stl(name)) {
-                                       if (is_stl_ascii(name))
-                                               read_stl_mesh_ascii(scene, name);
-                                       else
-                                               read_stl_mesh_binary(scene, name);
-                                       retval= BKE_READ_EXOTIC_OK_OTHER;
-                               }
-                               else {
-                                       retval= BKE_READ_EXOTIC_FAIL_FORMAT;
-                               }
-                               //XXX waitcursor(0);
-                       }
-               }
-       }
-       
-       return retval;
-}
-
-
-/* ************************ WRITE ************************** */
-
-static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL)
-{
-       float vert[3];
-
-       VECCOPY(vert, verts[(index)].co);
-       mul_m4_v3(ob->obmat, vert);
-
-       if (ENDIAN_ORDER==B_ENDIAN) {
-               SWITCH_INT(vert[0]);
-               SWITCH_INT(vert[1]);
-               SWITCH_INT(vert[2]);
-       }
-
-       fwrite(vert, sizeof(float), 3, fpSTL);
-}
-
-static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm)
-{
-       MVert *mvert = dm->getVertArray(dm);
-       MFace *mface = dm->getFaceArray(dm);
-       int i, numfacets = 0, totface = dm->getNumFaces(dm);
-       float zero[3] = {0.0f, 0.0f, 0.0f};
-
-       for (i=0; i<totface; i++, mface++) {
-               fwrite(zero, sizeof(float), 3, fpSTL);
-               write_vert_stl(ob, mvert, mface->v1, fpSTL);
-               write_vert_stl(ob, mvert, mface->v2, fpSTL);
-               write_vert_stl(ob, mvert, mface->v3, fpSTL);
-               fprintf(fpSTL, "  ");
-               numfacets++;
-
-               if(mface->v4) { /* quad = 2 tri's */
-                       fwrite(zero, sizeof(float), 3, fpSTL);
-                       write_vert_stl(ob, mvert, mface->v1, fpSTL);
-                       write_vert_stl(ob, mvert, mface->v3, fpSTL);
-                       write_vert_stl(ob, mvert, mface->v4, fpSTL);
-                       fprintf(fpSTL, "  ");
-                       numfacets++;
-               }
-       }
-
-       return numfacets;
-}
-
-static int write_object_stl(FILE *fpSTL, Scene *scene, Object *ob)
-{
-       int  numfacets = 0;
-       DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
-
-       numfacets += write_derivedmesh_stl(fpSTL, ob, dm);
-
-       dm->release(dm);
-
-       return numfacets;
-}
-
-void write_stl(Scene *scene, char *str)
-{
-       Object *ob;
-       Base   *base;
-       FILE   *fpSTL;
-       int    numfacets = 0;
-       ReportList *reports= NULL; /* XXX */
-
-       /* XXX, operator needs to manage filename extension */
-
-       fpSTL= fopen(str, "wb");
-       
-       if(fpSTL==NULL) {
-               BKE_reportf(reports, RPT_ERROR, "Can't open file: %s.", strerror(errno));
-               return;
-       }
-       
-       //XXX waitcursor(1);
-       
-       /* The header part of the STL */
-       /* First 80 characters are a title or whatever you want.
-          Lets make the first 32 of those spam and the rest the filename.
-          Those first 80 characters will be followed by 4 bytes
-          which will be overwritten later with an integer holding
-          how many facets are written (we set them to ' ' for now).
-       */
-       fprintf(fpSTL, "Binary STL output from Blender: %-48.48s    ", str);
-
-       /* Write all selected mesh objects */
-       base= scene->base.first;
-       while(base) {
-               if (base->flag & SELECT) {
-                       ob = base->object;
-                       if (ob->type == OB_MESH) {
-                               if(ob->data)
-                                       numfacets += write_object_stl(fpSTL, scene, ob);
-                       }
-               }
-               base= base->next;
-       }
-
-       /* time to write the number of facets in the 4 bytes
-          starting at byte 81
-       */
-       fseek(fpSTL, 80, SEEK_SET);
-
-       if (ENDIAN_ORDER==B_ENDIAN) {
-                               SWITCH_INT(numfacets);
-               }
-       fwrite(&numfacets, 4*sizeof(char), 1, fpSTL);
-
-       fclose(fpSTL);
-       
-       //XXX waitcursor(0);
-}
-
-
-static void replace_chars(char *str1, char *str2)
-{
-       int a= strlen(str2);
-       
-       str1[a]= 0;
-       while(a--) {
-               if(str2[a]=='.' || str2[a]==' ') str1[a]= '_';
-               else str1[a]= str2[a];
-       }
-}
-
-/* ******************************* WRITE DXF ***************************** */
-
-#define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data)
-
-/* A completely wacky function to try and make good
-indexed (AutoCAD index) values out of straight rgb 
-ones... crazy */
-
-static int rgb_to_dxf_col (float rf, float gf, float bf) 
-{
-       int r= (int) (rf*255.0f);
-       int g= (int) (gf*255.0f);
-       int b= (int) (bf*255.0f);
-       float h,s,v;
-       int ret;
-       
-       /* Grayscale value */
-       if (((int)r/10)==((int)g/10) && ((int)g/10)==((int)b/10)) ret= 250+((int)r/51);
-       /* A nice chroma value */
-       else {
-               rgb_to_hsv (rf,gf,bf,&h,&s,&v);
-               
-               ret= (int) (10.0f + (h*239.0f));
-               CLAMP(ret,10,249);
-               
-               /* If its whitish make the index odd */
-               if (s<.5 || v>.5) if(ret%2) ret++;
-       }
-       
-       return ret;
-}
-
-/* And its completely wacky complement */
-
-static void dxf_col_to_rgb (int cid, float *rf, float *gf, float *bf)
-{
-       float h, s, v;
-       
-       /* Grayscale values */
-       if (cid>=250 && cid <= 255) {
-               *rf= *gf= *bf= (float) ((cid-250)*51)/255;
-               CLAMP(*rf, 0.0, 1.0);
-               CLAMP(*gf, 0.0, 1.0);
-               CLAMP(*bf, 0.0, 1.0);
-               
-       /* Pure values */
-       } else if (cid<10) {
-               switch (cid) {
-               case 1:
-                       *rf=1.0;
-                       *gf=0.0;
-                       *bf=0.0;
-                       break;
-               case 2:
-                       *rf=1.0;
-                       *gf=1.0;
-                       *bf=0.0;
-                       break;
-               case 3:
-                       *gf=1.0;
-                       *rf=0.0;
-                       *bf=0.0;
-                       break;
-               case 4:
-                       *rf=0.0;
-                       *gf=1.0;
-                       *bf=1.0;
-                       break;
-               case 5:
-                       *rf=0.0;
-                       *gf=0.0;
-                       *bf=1.0;
-                       break;
-               case 6:
-                       *rf=1.0;
-                       *gf=0.0;
-                       *bf=1.0;
-                       break;
-               case 7:
-               default:
-                       *rf= *gf= *bf= 1.0;
-                       break;
-               }
-       } else {
-               /* Get chroma values */
-                       
-               h= (float) (cid-10)/239;
-               CLAMP(h, 0.0, 1.0);
-               
-               /* If its odd make it a bit whitish */
-               if (cid%2) { s=.75; v= 0.25; 
-               } else {  s= 0.25; v= 0.75;}
-               
-               hsv_to_rgb (h, s, v, rf, gf, bf);
-       }
-}
-
-static void write_mesh_dxf(FILE *fp, Mesh *me)
-{
-       Material *ma;
-       MVert *mvert;
-       MFace *mface;
-       int a;
-       char str[32];
-       
-       replace_chars(str, me->id.name+2);
-
-       write_group(0, "BLOCK");
-       
-       write_group(2, str); /* The name */
-               
-       write_group(8, "Meshes"); /* DXF Layer */
-       write_group(70, "64"); /* DXF block flags */
-       
-       write_group(10, "0.0"); /* X of base */
-       write_group(20, "0.0"); /* Y of base */
-       write_group(30, "0.0"); /* Z of base */
-
-       write_group(3, str); /* The name (again) */
-       
-       write_group(0, "POLYLINE"); /* Start the mesh */
-       write_group(66, "1"); /* Vertices follow flag */
-       write_group(8,"Meshes"); /* DXF Layer */
-
-       if (me->totcol) {
-               ma= me->mat[0];
-               if(ma) {
-                       sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
-                       write_group(62, str); /* Color index */
-               }
-       }
-
-       write_group(70, "64"); /* Polymesh mesh flag */
-       
-       fprintf(fp, "71\n%d\n", me->totvert); /* Total vertices */
-       fprintf(fp, "72\n%d\n", me->totface); /* Total faces */
-       
-       /* Write the vertices */
-       a= me->totvert;
-       mvert= me->mvert;
-       while(a--) {
-               write_group(0, "VERTEX"); /* Start a new vertex */
-               write_group(8, "Meshes"); /* DXF Layer */
-               fprintf (fp, "10\n%f\n", mvert->co[0]); /* X cord */
-               fprintf (fp, "20\n%f\n", mvert->co[1]); /* Y cord */
-               fprintf (fp, "30\n%f\n", mvert->co[2]); /* Z cord */
-               write_group(70, "192"); /* Polymesh vertex flag */
-                               
-               mvert++;
-       }
-
-       /* Write the face entries */
-       a= me->totface;
-       mface= me->mface;
-       while(a--) {
-               write_group(0, "VERTEX"); /* Start a new face */
-               write_group(8, "Meshes");
-       
-               /* Write a face color */
-               if (me->totcol) {
-                       ma= me->mat[(int)mface->mat_nr];
-                       if(ma) {
-                               sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b));
-                               write_group(62, str); /* Color index */
-                       }
-               }
-               else write_group(62, "254"); /* Color Index */
-
-               /* Not sure what this really corresponds too */
-               write_group(10, "0.0"); /* X of base */
-               write_group(20, "0.0"); /* Y of base */
-               write_group(30, "0.0"); /* Z of base */
-       
-               write_group(70, "128"); /* Polymesh face flag */
-       
-               if(mface->v4) {
-                       fprintf (fp, "71\n%d\n", mface->v1+1);
-                       fprintf (fp, "72\n%d\n", mface->v2+1);
-                       fprintf (fp, "73\n%d\n", mface->v3+1);
-                       fprintf (fp, "74\n%d\n", mface->v4+1);
-               } else {
-                       fprintf (fp, "71\n%d\n", mface->v1+1);
-                       fprintf (fp, "72\n%d\n", mface->v2+1);
-                       fprintf (fp, "73\n%d\n", mface->v3+1);
-               }
-               mface++;
-       }
-
-       write_group(0, "SEQEND");       
-       
-       write_group(0, "ENDBLK");
-}
-
-static void write_object_dxf(FILE *fp, Object *ob, int layer)
-{
-       ID *id;
-       char str[32];
-
-       id= ob->data;
-
-       write_group(0, "INSERT"); /* Start an insert group */
-       
-       sprintf(str, "%d", layer);
-       write_group(8, str);
-
-       replace_chars(str, id->name+2);
-       write_group(2, str);
-
-       fprintf (fp, "10\n%f\n", ob->loc[0]); /* X of base */
-       fprintf (fp, "20\n%f\n", ob->loc[1]); /* Y of base */
-       fprintf (fp, "30\n%f\n", ob->loc[2]); /* Z of base */
-       
-       fprintf (fp, "41\n%f\n", ob->size[0]); /* X scale */
-       fprintf (fp, "42\n%f\n", ob->size[1]); /* Y scale */
-       fprintf (fp, "43\n%f\n", ob->size[2]); /* Z scale */
-       
-       fprintf (fp, "50\n%f\n", (float) ob->rot[2]*180/M_PI); /* Can only write the Z rot */
-}
-
-void write_dxf(struct Scene *scene, char *str)
-{
-       Mesh *me;
-       Base *base;
-       FILE *fp;
-       
-       /* XXX, operator needs to handle overwrite & rename */
-
-       fp= fopen(str, "w");
-       
-       if(fp==NULL) {
-               //XXX error("Can't write file");
-               return;
-       }
-       
-       //XXX waitcursor(1);
-       
-       /* The header part of the DXF */
-       
-       write_group(0, "SECTION");
-       write_group(2, "HEADER");
-       write_group(0, "ENDSEC");
-
-       /* The blocks part of the DXF */
-       
-       write_group(0, "SECTION");
-       write_group(2, "BLOCKS");
-
-
-       /* only write meshes we're using in this scene */
-       flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0);
-       
-       for(base= scene->base.first; base; base= base->next)
-               if(base->object->type== OB_MESH)
-                       ((ID *)base->object->data)->flag |= LIB_DOIT;   
-       
-       /* Write all the meshes */
-       me= G.main->mesh.first;
-       while(me) {
-               if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */
-                       write_mesh_dxf(fp, me);
-               }
-               me= me->id.next;
-       }
-
-       write_group(0, "ENDSEC");
-
-       /* The entities part of the DXF */
-       
-       write_group(0, "SECTION");
-       write_group(2, "ENTITIES");
-
-       /* Write all the mesh objects */
-       base= scene->base.first;
-       while(base) {
-               if(base->object->type== OB_MESH) {
-                       write_object_dxf(fp, base->object, base->lay);
-               }
-               base= base->next;
-       }
-
-       write_group(0, "ENDSEC");
-       
-       /* Thats all */
-       
-       write_group(0, "EOF");
-       fclose(fp);
-       
-       //XXX waitcursor(0);
-}
-
-
-static int dxf_line= 0;
-static FILE *dxf_fp= NULL;
-
-/* exotic.c(2863) : note C6311: c:/Program Files/Microsoft Visual
- * Studio/VC98/include\ctype.h(268) : see previous definition of
- * 'iswspace' */
-#define ton_iswspace(c) (c==' '||c=='\n'||c=='\t')
-
-static void clean_wspace (char *str) 
-{
-       char *from, *to;
-       char t;
-       
-       from= str;
-       to=str;
-       
-       while (*from!=0) {
-               t= *from;
-               *to= t;
-               
-               if(!ton_iswspace(*from)) to++;
-               from++;
-       }
-       *to=0;
-}
-
-static int all_wspace(char *str)
-{
-       while(*str != 0) {
-               if (!ton_iswspace(*str)) return 0;
-               str++;
-       }
-
-       return 1;
-}
-
-static int all_digits(char *str)
-{
-       while(*str != 0) {
-               if (!isdigit(*str)) return 0;
-               str++;
-       }
-
-       return 1;
-}
-
-static int dxf_get_layer_col(char *UNUSED(layer)) 
-{
-       return 1;
-}
-
-static int dxf_get_layer_num(Scene *scene, char *layer)
-{
-       int ret = 0;
-
-       if (all_digits(layer) && atoi(layer)<(1<<20)) ret= atoi(layer);
-       if (ret == 0) ret = scene->lay;
-
-       return ret;
-}
-
-static void dos_clean(char *str)
-{
-       while (*str) {
-               if (*str == 0x0d) {
-                       *str='\n';
-                       *(++str)= 0;
-                       break;
-               }
-               str++;
-       }       
-}
-
-static void myfgets(char *str, int len, FILE *fp)
-{
-       char c;
-       
-       while(len>0 && (c=getc(dxf_fp)) ) {
-               *str= c;
-               str++;
-               len--;
-               /* three types of enters, \n \r and \r\n  */
-               if(c == '\n') break;
-               if(c=='\r') {
-                       c= getc(fp);                            // read the linefeed from stream
-                       if(c != 10) ungetc(c, fp);      // put back, if it's not one...
-                       break;
-               }
-       }
-}
-
-static int read_groupf(char *str) 
-{
-       short c;
-       int ret=-1;
-       char tmp[256];
-       
-       strcpy(str, " ");
-
-       while ((c=getc(dxf_fp)) && ton_iswspace(c));
-       ungetc(c, dxf_fp);
-       if (c==EOF) return -1;
-       
-       myfgets(tmp, 255, dxf_fp);
-       
-       dos_clean(tmp);
-
-       if(sscanf(tmp, "%d\n", &ret)!=1) return -2;
-               
-       myfgets(tmp, 255, dxf_fp);
-
-       dos_clean(tmp);
-
-       if (!all_wspace(tmp)) {
-               if (sscanf(tmp, "%s\n", str)!=1) return -2;
-       }
-       
-       clean_wspace(str);
-       dxf_line+=2;
-       
-       return ret;
-}
-
-//XXX error() is now printf until we have a callback error
-#define id_test(id) if(id<0) {char errmsg[128];fclose(dxf_fp); if(id==-1) sprintf(errmsg, "Error inputting dxf, near line %d", dxf_line); else if(id==-2) sprintf(errmsg, "Error reading dxf, near line %d", dxf_line);printf("%s", errmsg); return;}
-
-#define read_group(id,str) {id= read_groupf(str); id_test(id);}
-
-#define group_is(idtst,str) (id==idtst&&strcmp(val,str)==0)
-#define group_isnt(idtst,str) (id!=idtst||strcmp(val,str)!=0)
-#define id_check(idtst,str) if(group_isnt(idtst,str)) { fclose(dxf_fp); printf("Error parsing dxf, near line %d", dxf_line); return;}
-
-static int id;
-static char val[256];
-
-static short error_exit=0;
-static short hasbumped=0;
-
-static int is_dxf(const char *str)
-{      
-       dxf_line=0;
-       
-       dxf_fp= fopen(str, "r");
-       if (dxf_fp==NULL) return 0;
-
-       id= read_groupf(val);
-       if ((id==0 && strcmp(val, "SECTION")==0)||id==999) return 1;
-       
-       fclose(dxf_fp);
-       
-       return 0;
-}
-
-/* NOTES ON THE READER */ 
-/*
-       --
-       It turns out that most DXF writers like (LOVE) to
-       write meshes as a long string of 3DFACE entities.
-       This means the natural way to read a DXF file
-       (every entity corresponds to an object) is completely
-       unusable, reading in 10,000 faces each as an
-       object just doesn't cut it. Thus the 3DFACE
-       entry reader holds state, and only finalizes to
-       an object when a) the layer name changes, b) the
-       entry type changes, c) we are done reading.
-
-       PS... I decided to do the same thing with LINES, 
-       apparently the same thing happens sometimes as
-       well.
-
-       PPS... I decided to do the same thing with everything.
-       Now it is all really nasty and should be rewritten. 
-       --
-       
-       Added circular and elliptical arcs and lwpolylines.
-       These are all self-contained and have the size known
-       in advance, and so I haven't used the held state. -- martin
-*/
-
-static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer) 
-{
-       Material *ma;
-       
-       if (!me) return;
-       
-       if(ob) {
-               ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat");
-               ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits");
-               ob->actcol= 1;
-       }
-
-       me->totcol= 1;
-       me->mat= MEM_callocN(sizeof(void *)*1, "me->mat");
-       
-       if (color[0]<0) {
-               if (strlen(layer)) dxf_col_to_rgb(dxf_get_layer_col(layer), &color[0], &color[1], &color[2]);
-               color[0]= color[1]= color[2]= 0.8f;
-       }                                                                                               
-                                               
-       ma= G.main->mat.first;
-       while(ma) {
-               if(ma->mtex[0]==NULL) {
-                       if(color[0]==ma->r && color[1]==ma->g && color[2]==ma->b) {
-                               me->mat[0]= ma;
-                               ma->id.us++;
-                               break;
-                       }
-               }
-               ma= ma->id.next;
-       }
-       if(ma==NULL) {
-               ma= add_material("ext");
-               me->mat[0]= ma;
-               ma->r= color[0];
-               ma->g= color[1];
-               ma->b= color[2];
-               automatname(ma);
-       }
-}
-
-       /* General DXF vars */
-static float cent[3]={0.0, 0.0, 0.0};
-static char layname[32]="";
-static char entname[32]="";
-static float color[3]={-1.0, -1.0, -1.0};
-static float *vcenter;
-static float zerovec[3]= {0.0, 0.0, 0.0};
-
-#define reset_vars cent[0]= cent[1]= cent[2]=0.0; strcpy(layname, ""); color[0]= color[1]= color[2]= -1.0
-
-
-static void dxf_get_mesh(Scene *scene, Mesh** m, Object** o, int noob)
-{
-       Mesh *me = NULL;
-       Object *ob;
-       
-       if (!noob) {
-               *o = add_object(scene, OB_MESH);
-               ob = *o;
-               
-               if (entname[0]) new_id(&G.main->object, (ID *)ob, entname);
-               else if (layname[0]) new_id(&G.main->object, (ID *)ob,  layname);
-
-               if (layname[0]) ob->lay= dxf_get_layer_num(scene, layname);
-               else ob->lay= scene->lay;
-               // not nice i know... but add_object() sets active base, which needs layer setting too (ton)
-               scene->basact->lay= ob->lay;
-
-               *m = ob->data;
-               me= *m;
-
-               vcenter= ob->loc;
-       } 
-       else {
-               *o = NULL;
-               *m = add_mesh("Mesh");
-
-               me = *m;
-               ob = *o;
-               
-               ((ID *)me)->us=0;
-
-               if (entname[0]) new_id(&G.main->mesh, (ID *)me, entname);
-               else if (layname[0]) new_id(&G.main->mesh, (ID *)me, layname);
-
-               vcenter = zerovec;
-       }
-       me->totvert=0;
-       me->totface=0;
-       me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, 0);
-       me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
-}
-
-static void dxf_read_point(Scene *scene, int noob) {   
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       MVert *mvert;
-       
-       reset_vars;
-
-       read_group(id, val);                                                            
-       while(id!=0) {
-               if (id==8) {
-                       BLI_strncpy(layname, val, sizeof(layname));
-               } else if (id==10) {
-                       cent[0]= (float) atof(val);
-               } else if (id==20) {
-                       cent[1]= (float) atof(val);
-               } else if (id==30) {
-                       cent[2]= (float) atof(val);
-               } else if (id==60) {
-                       /* short invisible= atoi(val); */
-               } else if (id==62) {
-                       int colorid= atoi(val);
-                                                       
-                       CLAMP(colorid, 1, 255);
-                       dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
-               }
-               read_group(id, val);                                                            
-       }
-
-       dxf_get_mesh(scene, &me, &ob, noob);
-       me->totvert= 1;
-       me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
-       
-       dxf_add_mat (ob, me, color, layname);                                   
-
-       mvert= me->mvert;
-       mvert->co[0]= mvert->co[1]= mvert->co[2]= 0;
-               
-       if (ob) VECCOPY(ob->loc, cent);
-
-       hasbumped=1;
-}
-
-       /* Line state vars */
-static Object *linehold=NULL;
-static Mesh *linemhold=NULL;
-
-static char oldllay[32];
-static short lwasline=0; /* last was face 3d? */
-
-static void dxf_close_line(void)
-{
-       linemhold=NULL;
-       if (linehold==NULL) return;
-       
-       linehold=NULL;
-}
-
-static void dxf_read_line(Scene *scene, int noob) {    
-       /* Entity specific vars */
-       float epoint[3]={0.0, 0.0, 0.0};
-       short vspace=0; /* Whether or not coords are relative */
-       
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       MVert *mvert, *vtmp;
-       MFace *mface, *ftmp;
-       
-       reset_vars;
-
-       read_group(id, val);                                                            
-       while(id!=0) {
-               if (id==8) {
-                       BLI_strncpy(layname, val, sizeof(layname));
-               } else if (id==10) {
-                       cent[0]= (float) atof(val);
-               } else if (id==20) {
-                       cent[1]= (float) atof(val);
-               } else if (id==30) {
-                       cent[2]= (float) atof(val);
-               } else if (id==11) {
-                       epoint[0]= (float) atof(val);
-               } else if (id==21) {
-                       epoint[1]= (float) atof(val);
-               } else if (id==31) {
-                       epoint[2]= (float) atof(val);
-               } else if (id==60) {
-                       /* short invisible= atoi(val); */
-               } else if (id==62) {
-                       int colorid= atoi(val);
-                                                       
-                       CLAMP(colorid, 1, 255);
-                       dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
-               } else if (id==67) {
-                       vspace= atoi(val);
-               }
-               read_group(id, val);                                                            
-       }
-
-       /* Check to see if we need to make a new object */
-
-       if(!lwasline || strcmp(layname, oldllay)!=0) 
-               dxf_close_line();
-       if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS) 
-               dxf_close_line();
-                                       
-       if (linemhold==NULL) {
-               dxf_get_mesh(scene, &me, &ob, noob);
-
-               if(ob) VECCOPY(ob->loc, cent);
-
-               dxf_add_mat (ob, me, color, layname);
-
-               linehold= ob;
-               linemhold= me;
-       } else {
-               ob= linehold;
-               me= linemhold;
-       }
-
-       me->totvert+= 2;
-       me->totface++;
-       
-       vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
-
-       if(me->mvert) {
-               memcpy(vtmp, me->mvert, (me->totvert-2)*sizeof(MVert));
-               MEM_freeN(me->mvert);
-       }
-       me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
-       vtmp=NULL;
-
-       if(me->mface) {
-               memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
-               MEM_freeN(me->mface);
-       }
-       me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
-       ftmp=NULL;
-       
-       mvert= &me->mvert[(me->totvert-2)];
-
-       sub_v3_v3v3(mvert->co, cent, vcenter);
-       mvert++;
-       if (vspace) { VECCOPY(mvert->co, epoint);
-       } else sub_v3_v3v3(mvert->co, epoint, vcenter);
-               
-       mface= &(((MFace*)me->mface)[me->totface-1]);
-       mface->v1= me->totvert-2;
-       mface->v2= me->totvert-1;
-       mface->mat_nr= 0;
-
-       hasbumped=1;
-}
-
-               /* 2D Polyline state vars */
-static Object *p2dhold=NULL;
-static Mesh *p2dmhold=NULL;
-static char oldplay[32];
-static short lwasp2d=0;
-
-static void dxf_close_2dpoly(void)
-{
-       p2dmhold= NULL;
-       if (p2dhold==NULL) return;
-
-       p2dhold=NULL;
-}
-
-static void dxf_read_ellipse(Scene *scene, int noob) 
-{
-
-       /*
-   * The Parameter option of the ELLIPSE command uses the following equation to define an elliptical arc.
-   *
-   *    p(u)=c+a*cos(u)+b*sin(u)
-   *
-        * The variables a, b, c are determined when you select the endpoints for the
-        * first axis and the distance for the second axis. a is the negative of 1/2
-        * of the major axis length, b is the negative of 1/2 the minor axis length,
-        * and c is the center point (2-D) of the ellipse.
-   *
-        * Because this is actually a vector equation and the variable c is actually
-        * a point with X and Y values, it really should be written as:
-   *
-   *   p(u)=(Cx+a*cos(u))*i+(Cy+b*sin(u))*j
-   *
-   * where
-   *
-   *   Cx is the X value of the point c
-   *   Cy is the Y value of the point c
-   *   a is -(1/2 of the major axis length)
-   *   b is -(1/2 of the minor axis length)
-   *   i and j represent unit vectors in the X and Y directions
-        *
-        * http://astronomy.swin.edu.au/~pbourke/geomformats/dxf2000/ellipse_command39s_parameter_option_dxf_06.htm
-        * (reproduced with permission)
-        * 
-        * NOTE: The start and end angles ('parameters') are in radians, whereas those for the circular arc are 
-        * in degrees. The 'sense' of u appears to be determined by the extrusion direction (see more detailed comment
-        * in the code)
-        *
-        * TODO: The code is specific to ellipses in the x-y plane right now.
-        * 
-        */
-       
-       /* Entity specific vars */
-       float epoint[3]={0.0, 0.0, 0.0};
-       float center[3]={0.0, 0.0, 0.0};
-       float extrusion[3]={0.0, 0.0, 1.0}; 
-       float axis_endpoint[3] = {0.0, 0.0, 0.0}; /* major axis endpoint */
-       short vspace=0; /* Whether or not coords are relative */
-       float a, b, x, y, z;
-       float phid = 0.0f, phi = 0.0f, theta = 0.0f;
-       float start_angle = 0.0f;
-       float end_angle = 2*M_PI;
-       float axis_ratio = 1.0f;
-       float temp;
-       int v, tot;
-       int isArc=0;
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       MVert *mvert;
-       MFace *mface;
-       
-       reset_vars;
-       read_group(id, val);                                                            
-       while(id!=0) {
-         if (id==8) {
-               BLI_strncpy(layname, val, sizeof(layname));
-         } else if (id==10) {
-               center[0]= (float) atof(val);
-         } else if (id==20) {
-               center[1]= (float) atof(val);
-         } else if (id==30) {
-               center[2]= (float) atof(val);
-         } else if (id==11) {
-               axis_endpoint[0]= (float) atof(val);
-         } else if (id==21) {
-               axis_endpoint[1]= (float) atof(val);
-         } else if (id==31) {
-               axis_endpoint[2]= (float) atof(val);
-         } else if (id==40) {
-               axis_ratio = (float) atof(val);
-               } else if (id==41) {
-                       printf("dxf: start = %f", atof(val) * 180/M_PI);
-               start_angle = -atof(val) + M_PI_2;
-         } else if (id==42) {
-                       printf("dxf: end = %f", atof(val) * 180/M_PI);
-                       end_angle = -atof(val) + M_PI_2; 
-         } else if (id==62) {
-               int colorid= atoi(val);
-               CLAMP(colorid, 1, 255);
-               dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
-         } else if (id==67) {
-               vspace= atoi(val);
-         } else if (id==100) {
-               isArc = 1;
-         } else if (id==210) {
-                       extrusion[0] = atof(val);
-               } else if (id==220) {
-                       extrusion[1] = atof(val);
-               } else if (id==230) {
-                       extrusion[2] = atof(val);
-               }
-         read_group(id, val);
-       }
-
-       if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line();
-       if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS) 
-         dxf_close_line();
-
-       /* The 'extrusion direction' seems akin to a face normal, 
-        * insofar as it determines the direction of increasing phi.
-        * This is again x-y plane specific; it should be fixed at 
-        * some point. */
-       
-       if (extrusion[2] < 0) {
-               temp = start_angle;
-               start_angle = M_PI - end_angle;
-               end_angle = M_PI - temp;
-       }
-       
-       if(end_angle > start_angle)
-         end_angle -= 2 * M_PI;
-
-       phi = start_angle;
-       
-       x = axis_endpoint[0]; 
-       y = axis_endpoint[1];
-       z = axis_endpoint[2];
-       a = sqrt(x*x + y*y + z*z);
-       b = a * axis_ratio;
-
-       theta = atan2(y, x);
-
-       x = a * sin(phi);
-       y = b * cos(phi);       
-
-#ifndef DEBUG_CENTER
-       epoint[0] = center[0] + x*cos(theta) - y*sin(theta);
-       epoint[1] = center[1] + x*sin(theta) + y*cos(theta);
-       epoint[2] = center[2];
-       
-
-       cent[0]= epoint[0];
-       cent[1]= epoint[1];
-       cent[2]= epoint[2];
-#else
-       cent[0]= center[0];
-       cent[1]= center[1];
-       cent[2]= center[2];
-#endif
-       
-       dxf_get_mesh(scene, &me, &ob, noob);
-       strcpy(oldllay, layname);               
-       if(ob) VECCOPY(ob->loc, cent);
-       dxf_add_mat (ob, me, color, layname);
-
-       tot = 32; /* # of line segments to divide the arc into */
-
-       phid = (end_angle - start_angle)/tot; 
-
-       me->totvert += tot+1;
-       me->totface += tot+1;
-       
-       me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
-
-       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
-       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
-       printf("vertex and face buffers allocated\n");
-
-       for(v = 0; v <= tot; v++) {
-
-               x = a * sin(phi);
-               y = b * cos(phi);       
-               epoint[0] = center[0] + x*cos(theta) - y*sin(theta);
-               epoint[1] = center[1] + x*sin(theta) + y*cos(theta);
-               epoint[2] = center[2];
-         
-               mvert= &me->mvert[v];
-               
-               if (vspace) {
-                       VECCOPY(mvert->co, epoint);
-               }       else {
-                       sub_v3_v3v3(mvert->co, epoint, vcenter);
-               }
-
-               if (v > 0) {
-                       mface= &(((MFace*)me->mface)[v-1]);
-                       mface->v1 = v-1;
-                       mface->v2 = v;
-                       mface->mat_nr = 0;
-               }
-         
-               hasbumped = 1;
-
-               VECCOPY(cent, epoint);    
-               phi+=phid;
-       }
-}
-
-static void dxf_read_arc(Scene *scene, int noob) 
-{
-       /* Entity specific vars */
-       float epoint[3]={0.0, 0.0, 0.0};
-       float center[3]={0.0, 0.0, 0.0};
-       float extrusion[3]={0.0, 0.0, 1.0};
-       short vspace=0; /* Whether or not coords are relative */
-       float dia = 0.0f;
-       float phid = 0.0f, phi = 0.0f;
-       float start_angle = 0.0f;
-       float end_angle = 2*M_PI;
-       float temp;
-       int v, tot = 32;
-       int isArc=0;
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       MVert *mvert;
-       MFace *mface;
-       
-       reset_vars;
-       read_group(id, val);                                                            
-       while(id!=0) {
-         if (id==8) {
-               BLI_strncpy(layname, val, sizeof(layname));
-         } else if (id==10) {
-               center[0]= (float) atof(val);
-         } else if (id==20) {
-               center[1]= (float) atof(val);
-         } else if (id==30) {
-               center[2]= (float) atof(val);
-         } else if (id==40) {
-               dia = (float) atof(val);
-         } else if (id==62) {
-               int colorid= atoi(val);
-
-               CLAMP(colorid, 1, 255);
-               dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
-         } else if (id==67) {
-               vspace= atoi(val);
-         } else if (id==100) {
-               isArc = 1;
-         } else if (id==50) {
-               start_angle = (90 - atoi(val)) * M_PI/180.0;
-         } else if (id==51) {
-               end_angle = (90 - atoi(val)) * M_PI/180.0;
-         } else if (id==210) {
-                       extrusion[0] = atof(val);
-               } else if (id==220) {
-                       extrusion[1] = atof(val);
-               } else if (id==230) {
-                       extrusion[2] = atof(val);
-               }
-         read_group(id, val);
-       }
-
-       if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line();
-       if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS) 
-         dxf_close_line();
-       
-       /* Same xy-plane-specific extrusion direction code as in read_ellipse
-        * (read_arc and read_ellipse should ideally be rewritten to share code)
-        */
-       
-       if (extrusion[2] < 0) {
-               temp = start_angle;
-               start_angle = M_PI - end_angle;
-               end_angle = M_PI - temp;
-       }
-       
-       phi = start_angle;
-       if(end_angle > start_angle)
-         end_angle -= 2 * M_PI;
-
-       cent[0]= center[0]+dia*sin(phi);
-       cent[1]= center[1]+dia*cos(phi);
-       cent[2]= center[2];
-
-       dxf_get_mesh(scene, &me, &ob, noob);
-       BLI_strncpy(oldllay, layname, sizeof(oldllay));
-       if(ob) VECCOPY(ob->loc, cent);
-       dxf_add_mat (ob, me, color, layname);
-
-       tot = 32; /* # of line segments to divide the arc into */
-       phid = (end_angle - start_angle)/tot; /* fix so that arcs have the same 'resolution' as circles? */
-
-       me->totvert += tot+1;
-       me->totface += tot+1;
-       
-       me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
-
-       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
-       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
-       for(v = 0; v <= tot; v++) { 
-
-               epoint[0]= center[0]+dia*sin(phi);
-               epoint[1]= center[1]+dia*cos(phi);
-               epoint[2]= center[2];
-
-               mvert= &me->mvert[v];
-               
-               if (vspace) {
-                       VECCOPY(mvert->co, epoint);
-               } else {
-                       sub_v3_v3v3(mvert->co, epoint, vcenter);
-               }
-
-               if (v > 0) {
-                       mface= &(((MFace*)me->mface)[v-1]);
-                       mface->v1 = v-1;
-                       mface->v2 = v;
-                       mface->mat_nr = 0;
-               }
-         
-               hasbumped=1;
-
-               VECCOPY(cent, epoint);    
-               phi+=phid;
-       }
-}
-
-static void dxf_read_polyline(Scene *scene, int noob) {        
-       /* Entity specific vars */
-       short vspace=0; /* Whether or not coords are relative */
-       int flag=0;
-       int vflags=0;
-       int vids[4];
-       int nverts;
-       
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       float vert[3] = {0};
-       
-       MVert *mvert, *vtmp;
-       MFace *mface, *ftmp;
-       
-       reset_vars;
-
-       read_group(id, val);                                                            
-       while(id!=0) {
-               if (id==8) {
-                       BLI_strncpy(layname, val, sizeof(layname));
-               } else if (id==10) {
-                       cent[0]= (float) atof(val);
-               } else if (id==20) {
-                       cent[1]= (float) atof(val);
-               } else if (id==30) {
-                       cent[2]= (float) atof(val);
-               } else if (id==60) {
-                       /* short invisible= atoi(val); */
-               } else if (id==62) {
-                       int colorid= atoi(val);
-                                                       
-                       CLAMP(colorid, 1, 255);
-                       dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
-               } else if (id==67) {
-                       vspace= atoi(val);
-               } else if (id==70) {
-                       flag= atoi(val);                        
-               }
-               read_group(id, val);                                                            
-       }
-
-       if (flag & 9) { // 1= closed curve, 8= 3d curve
-               if(!lwasp2d || strcmp(layname, oldplay)!=0) dxf_close_2dpoly();
-               if(p2dmhold != NULL && p2dmhold->totvert>MESH_MAX_VERTS)
-                       dxf_close_2dpoly();
-
-               if (p2dmhold==NULL) {
-                       dxf_get_mesh(scene, &me, &ob, noob);
-
-                       strcpy(oldplay, layname);
-                               
-                       if(ob) VECCOPY(ob->loc, cent);
-               
-                       dxf_add_mat (ob, me, color, layname);
-               
-                       p2dhold= ob;
-                       p2dmhold= me;
-               } 
-               else {
-                       ob= p2dhold;
-                       me= p2dmhold;
-               }
-               
-               nverts=0;
-               while (group_is(0, "VERTEX")) {
-                       read_group(id, val);
-                       while(id!=0) {
-                               if (id==10) {
-                                       vert[0]= (float) atof(val);
-                               } else if (id==20) {
-                                       vert[1]= (float) atof(val);
-                               } else if (id==30) {
-                                       vert[2]= (float) atof(val);
-                               }
-                               read_group(id, val);
-                       }
-                       nverts++;
-                       me->totvert++;
-                       
-                       vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-                       
-                       if (me->mvert) {
-                               memcpy (vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
-                               MEM_freeN(me->mvert);
-                       }
-                       me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
-                       vtmp= NULL;
-                       
-                       mvert= &me->mvert[me->totvert-1];
-                       
-                       if (vspace) { VECCOPY(mvert->co, vert);
-                       } else sub_v3_v3v3(mvert->co, vert, vcenter);
-               }
-               
-               /* make edges */
-               if(nverts>1) {
-                       int a, oldtotface;
-                       
-                       oldtotface= me->totface;
-                       me->totface+= nverts-1;
-
-                       ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface");
-
-                       if(me->mface) {
-                               memcpy(ftmp, me->mface, oldtotface*sizeof(MFace));
-                               MEM_freeN(me->mface);
-                       }
-                       me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
-                       ftmp=NULL;
-
-                       mface= me->mface;
-                       mface+= oldtotface;
-                       
-                       for(a=1; a<nverts; a++, mface++) {
-                               mface->v1= (me->totvert-nverts)+a-1;
-                               mface->v2= (me->totvert-nverts)+a;
-                               mface->mat_nr= 0;
-                       }
-               }
-               
-               lwasp2d=1;
-       } 
-       else if (flag&64) {
-               dxf_get_mesh(scene, &me, &ob, noob);
-               
-               if(ob) VECCOPY(ob->loc, cent);
-       
-               dxf_add_mat (ob, me, color, layname);
-
-               while (group_is(0, "VERTEX")) {
-                       vflags= 0;
-                       vids[0]= vids[1]= vids[2]= vids[3]= 0;
-               
-                       vflags=0;
-                       read_group(id, val);
-                       while(id!=0) {
-                               if(id==8) {
-                                       ; /* Layer def, skip */
-                               } else if (id==10) {
-                                       vert[0]= (float) atof(val);
-                               } else if (id==20) {
-                                       vert[1]= (float) atof(val);
-                               } else if (id==30) {
-                                       vert[2]= (float) atof(val);
-                               } else if (id==70) {
-                                       vflags= atoi(val);
-                               } else if (id==71) {
-                                       vids[0]= abs(atoi(val));
-                               } else if (id==72) {
-                                       vids[1]= abs(atoi(val));
-                               } else if (id==73) {
-                                       vids[2]= abs(atoi(val));
-                               } else if (id==74) {
-                                       vids[3]= abs(atoi(val));
-                               }
-                               read_group(id, val);
-                       }
-                       
-                       if (vflags & 128 && vflags & 64) {
-                               me->totvert++;
-                               
-                               /* If we are nearing the limit scan to the next entry */
-                               if(me->totvert > MESH_MAX_VERTS) 
-                                       while(group_isnt(0, "SEQEND")) read_group(id, val);
-               
-                               vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       
-                               if(me->mvert) {
-                                       memcpy(vtmp, me->mvert, (me->totvert-1)*sizeof(MVert));
-                                       MEM_freeN(me->mvert);
-                               }
-                               me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp);
-                               vtmp=NULL;
-                               
-                               mvert= &me->mvert[(me->totvert-1)];
-       
-                               if (vspace) { VECCOPY(mvert->co, vert);
-                               } else sub_v3_v3v3(mvert->co, vert, vcenter);
-       
-                       } else if (vflags & 128) {
-                               if(vids[2]==0) {
-                                       //XXX error("(PL) Error parsing dxf, not enough vertices near line %d", dxf_line);
-                       
-                                       error_exit=1;
-                                       fclose(dxf_fp);
-                                       return;
-                               }
-       
-                               me->totface++;
-               
-                               ftmp= MEM_callocN(me->totface*sizeof(MFace), "mfaces");
-       
-                               if(me->mface) {
-                                       memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace));
-                                       MEM_freeN(me->mface);
-                               }
-                               me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp);
-                               ftmp=NULL;                      
-                               
-                               mface= &(((MFace*)me->mface)[me->totface-1]);
-                               mface->v1= vids[0]-1;
-                               mface->v2= vids[1]-1;
-                               mface->v3= vids[2]-1;
-       
-                               if(vids[3] && vids[3]!=vids[0]) {
-                                       mface->v4= vids[3]-1;
-                                       test_index_face(mface, NULL, 0, 4);
-                               }
-                               else test_index_face(mface, NULL, 0, 3);
-       
-                               mface->mat_nr= 0;
-       
-                       } else {
-                               //XXX error("Error parsing dxf, unknown polyline information near %d", dxf_line);
-                       
-                               error_exit=1;
-                               fclose(dxf_fp);
-                               return;
-                       }
-       
-               }       
-       }
-}
-
-static void dxf_read_lwpolyline(Scene *scene, int noob) {      
-       /* Entity specific vars */
-       short vspace=0; /* Whether or not coords are relative */
-       int flag=0;
-       int nverts=0;
-       int v;
-       
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       float vert[3] = {0};
-       
-       MVert *mvert;
-       MFace *mface;
-       
-       reset_vars;
-
-       id = -1;
-
-       /* block structure is
-        * {...}
-        * 90 => nverts
-        * 70 => flags
-        * nverts.times { 10 => x, 20 => y }
-        */
-       while(id!=70)   {
-               read_group(id, val);                                                            
-               if (id==8) {
-                       BLI_strncpy(layname, val, sizeof(layname));
-               } else if (id==38) {
-                       vert[2]= (float) atof(val);
-               } else if (id==60) {
-                       /* short invisible= atoi(val); */
-               } else if (id==62) {
-                       int colorid= atoi(val);
-                                                       
-                       CLAMP(colorid, 1, 255);
-                       dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]);
-               } else if (id==67) {
-                       vspace= atoi(val);
-               } else if (id==70) {
-                       flag= atoi(val);                        
-               } else if (id==90) {
-                       nverts= atoi(val);
-               }
-       } 
-       printf("nverts %d\n", nverts);  
-       if (nverts == 0)
-               return;
-
-       dxf_get_mesh(scene, &me, &ob, noob);
-       strcpy(oldllay, layname);               
-       if(ob) VECCOPY(ob->loc, cent);
-       dxf_add_mat (ob, me, color, layname);
-
-       me->totvert += nverts;
-       me->totface += nverts;
-
-       me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts");
-       me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface");
-
-       CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert);
-       CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
-       for (v = 0; v < nverts; v++) {
-               read_group(id,val);
-               if (id == 10) {
-                       vert[0]= (float) atof(val);
-               } else {
-                       //XXX error("Error parsing dxf, expected (10, <x>) at line %d", dxf_line);      
-               }
-
-               read_group(id,val);
-               if (id == 20) {
-                       vert[1]= (float) atof(val);
-               } else {
-                       //XXX error("Error parsing dxf, expected (20, <y>) at line %d", dxf_line);      
-               }
-               
-               mvert = &me->mvert[v];
-
-               if (vspace) { 
-                       VECCOPY(mvert->co, vert);
-               } else {
-                       sub_v3_v3v3(mvert->co, vert, vcenter);
-               }
-
-               if (v > 0) {
-                       mface= &(((MFace*)me->mface)[v-1]);
-                       mface->v1 = v-1;
-                       mface->v2 = v;
-                       mface->mat_nr = 0;
-               }
-       }
-
-       /* flag & 1 -> closed polyline 
-   * TODO: give the polyline actual 2D faces if it is closed */
-
-       if (flag&1) {
-               if(me->mface) {
-                       mface= &(((MFace*)me->mface)[nverts - 1]);
-                       mface->v1 = nverts-1;
-                       mface->v2 = 0;
-                       mface->mat_nr = 0;
-               }
-       }  
-}
-
-
-       /* 3D Face state vars */
-static Object *f3dhold=NULL;
-static Mesh *f3dmhold=NULL;
-static char oldflay[32];
-static short lwasf3d=0; /* last was face 3d? */
-
-/* how can this function do anything useful (ton)? */
-static void dxf_close_3dface(void)
-{
-       f3dmhold= NULL;
-       if (f3dhold==NULL) return;
-       
-       f3dhold=NULL;
-}
-
-static void dxf_read_3dface(Scene *scene, int noob) 
-{      
-       /* Entity specific vars */
-       float vert2[3]={0.0, 0.0, 0.0};
-       float vert3[3]={0.0, 0.0, 0.0};
-       float vert4[3]={0.0, 0.0, 0.0};
-       short vspace=0;
-
-       int nverts=0;
-       
-       /* Blender vars */
-       Object *ob;
-       Mesh *me;
-       MVert *mvert, *vtmp;
-       MFace *mface, *ftmp;
-       
-       reset_vars;
-
-       read_group(id, val);                                                            
-       while(id!=0) {
-               if (id==8) {
-                       BLI_strncpy(layname, val, sizeof(layname));
-               
-               /* First vert/origin */
-               } else if (id==10) {
-                       cent[0]= (float) atof(val);
-                       if (nverts<1)nverts++;
-               } else if (id==20) {
-                       cent[1]= (float) atof(val);
-                       if (nverts<1)nverts++;
-               } else if (id==30) {
-                       cent[2]= (float) atof(val);
-                       if (nverts<1)nverts++;
-                       
-               /* Second vert */
-               } else if (id==11) {
-                       vert2[0]= (float) atof(val);
-                       if (nverts<2)nverts++;
-               } else if (id==21) {
-                       vert2[1]= (float) atof(val);
-                       if (nverts<2)nverts++;
-               } else if (id==31) {
-                       vert2[2]= (float) atof(val);
-                       if (nverts<2)nverts++;
-               
-               /* Third vert */
-               } else if (id==12) {
-                       vert3[0]= (float) atof(val);
-                       if (nverts<3)nverts++;
-               } else if (id==22) {
-                       vert3[1]= (float) atof(val);
-                       if (nverts<3)nverts++;
-               } else if (id==32) {
-                       vert3[2]= (float) atof(val);
-                       if (nverts<3)nverts++;
-                       
-               /* Fourth vert */
-               } else if (id==13) {
-                       vert4[0]= (float) atof(val);
-                       if (nverts<4)nverts++;
-               } else if (id==23) {
-                       vert4[1]= (float) atof(val);
-                       if (nverts<4)nverts++;
-               } else if (id==33) {
-                       vert4[2]= (float) atof(val);
-                       if (nverts<4)nverts++;
-                       
-               /* Other */
-               } else if (id==60) {
-                       /* short invisible= atoi(val); */
-               } else if (id==62) {
-                       int colorid= atoi(val);
-                                                       
-                       CLAMP(colorid, 1, 255);
-                       dxf_col_to_rgb(colorid, &color[0], &color[1],