svn merge -r 14721:14810 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 12 May 2008 12:24:52 +0000 (12:24 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 12 May 2008 12:24:52 +0000 (12:24 +0000)
101 files changed:
intern/ghost/intern/GHOST_NDOFManager.cpp
intern/ghost/intern/GHOST_System.cpp
release/Makefile
release/scripts/3ds_export.py
release/scripts/bevel_center.py
release/scripts/blenderLipSynchro.py
release/scripts/bpymodules/BPyAddMesh.py
release/scripts/bpymodules/dxfReader.py
release/scripts/export_m3g.py
release/scripts/hotkeys.py
release/scripts/import_dxf.py
release/scripts/object_apply_def.py
release/scripts/paths_import.py
release/scripts/render_save_layers.py
release/scripts/rvk1_torvk2.py
release/scripts/x3d_export.py
source/Makefile
source/blender/blenkernel/BKE_idprop.h
source/blender/blenkernel/BKE_writeffmpeg.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/collision.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/ipo.c
source/blender/blenkernel/intern/mball.c
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/blenlib/BLI_arithb.h
source/blender/blenlib/BLI_edgehash.h
source/blender/blenlib/BLI_kdopbvh.h
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/blenlib/intern/arithb.c
source/blender/blenlib/intern/edgehash.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/include/BDR_editface.h
source/blender/include/BIF_drawseq.h
source/blender/include/BIF_editmesh.h
source/blender/include/BIF_interface.h
source/blender/makesdna/DNA_particle_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/nodes/intern/CMP_nodes/CMP_displace.c
source/blender/nodes/intern/CMP_nodes/CMP_hueSatVal.c
source/blender/nodes/intern/SHD_nodes/SHD_hueSatVal.c
source/blender/python/BPY_interface.c
source/blender/python/api2_2x/Blender.c
source/blender/python/api2_2x/Object.c
source/blender/python/api2_2x/Particle.c
source/blender/python/api2_2x/Particle.h
source/blender/python/api2_2x/doc/API_intro.py
source/blender/python/api2_2x/doc/Object.py
source/blender/python/api2_2x/doc/Particle.py [new file with mode: 0644]
source/blender/python/api2_2x/doc/epy_docgen-3.sh [deleted file]
source/blender/python/api2_2x/doc/epy_docgen.sh
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/shadeoutput.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_object.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/drawimage.c
source/blender/src/drawimasel.c
source/blender/src/drawnla.c
source/blender/src/drawobject.c
source/blender/src/drawseq.c
source/blender/src/drawview.c
source/blender/src/edit.c
source/blender/src/editarmature.c
source/blender/src/editdeform.c
source/blender/src/editface.c
source/blender/src/editmesh_lib.c
source/blender/src/editmesh_mods.c
source/blender/src/editobject.c
source/blender/src/editseq.c
source/blender/src/editsima.c
source/blender/src/header_image.c
source/blender/src/header_seq.c
source/blender/src/header_view3d.c
source/blender/src/interface.c
source/blender/src/interface_draw.c
source/blender/src/parametrizer.c
source/blender/src/parametrizer.h
source/blender/src/parametrizer_intern.h
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/splash.jpg.c
source/blender/src/toets.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/blender/src/transform_manipulator.c
source/blender/src/transform_orientations.c
source/blender/src/unwrapper.c
source/gameengine/GamePlayer/Makefile
source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
source/gameengine/Ketsji/KX_CameraActuator.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/PyDoc/GameLogic.py
source/nan_definitions.mk

index 6f3876c1d960e5c755e36187f54f11c48a1b4c1c..2426146184a7f767da31f1e7d4cb0c8c2479ed93 100644 (file)
@@ -73,7 +73,9 @@ GHOST_NDOFManager::deviceOpen(GHOST_IWindow* window,
     if (ndofLibraryInit  && ndofDeviceOpen)
     {
        Pid= ndofLibraryInit();
+#if 0
                printf("%i client \n", Pid);
+#endif
                #if defined(_WIN32) || defined(__APPLE__)
                        m_DeviceHandle = ndofDeviceOpen((void *)&currentNdofValues);    
                #else
index 458a35bf34b7c10e3db67c477708a6f6df450d30..87e5f375958511fa1f5596d52a8ffcd30a151db5 100644 (file)
@@ -283,9 +283,11 @@ GHOST_TSuccess GHOST_System::init()
        m_eventManager = new GHOST_EventManager ();
     m_ndofManager = new GHOST_NDOFManager();
 
+#if 0
        if(m_ndofManager)
                printf("ndof manager \n");
-
+#endif
+       
 #ifdef GHOST_DEBUG
        if (m_eventManager) {
                m_eventManager->addConsumer(&m_eventPrinter);
index 953144b522340180a1a387897846025c007787c5..f440e2dface576b478221895a35c0be860c7118d 100644 (file)
@@ -118,7 +118,6 @@ install: package
     ifneq ($(OS), darwin)
        @[ ! -d $(OCGDIR)/bin/.blender ] || \
                cp -r $(OCGDIR)/bin/.blender $(DISTDIR)
-       @rm -rf $(DISTDIR)/.svn $(DISTDIR)/*/.svn $(DISTDIR)/*/*/.svn
        @cp $(NANBLENDERHOME)/bin/.blender/.Blanguages $(CONFDIR)
        @cp $(NANBLENDERHOME)/bin/.blender/.bfont.ttf $(CONFDIR)
     endif
@@ -144,8 +143,7 @@ ifneq ($(NOPLUGINS),true)
        @cp ../source/blender/blenpluginapi/*.h $(DISTDIR)/plugins/include/
        @chmod 755 $(DISTDIR)/plugins/bmake
        @$(MAKE) -C $(DISTDIR)/plugins all  > /dev/null || exit 1;
-       @rm -fr $(DISTDIR)/plugins/.svn $(DISTDIR)/plugins/*/.svn \
-             $(DISTDIR)/plugins/*/*.o
+       @rm -f $(DISTDIR)/plugins/*/*.o
 
 #on OS X the plugins move to the installation directory
     ifneq ($(OS),darwin)
@@ -158,7 +156,6 @@ endif
 
        @echo "----> Copy python infrastructure"
        @[ ! -d scripts ] || cp -r scripts $(CONFDIR)/scripts
-       @[ ! -d $(CONFDIR)/scripts ] || rm -fr $(CONFDIR)/scripts/.svn $(CONFDIR)/scripts/*/.svn $(CONFDIR)/scripts/*/*/.svn
 
     ifeq ($(OS),darwin)
        @echo "----> Move .blender to .app/Contents/MacOS/"
@@ -180,6 +177,8 @@ endif
        @[ ! -x $(CONFIG_GUESS)/specific.sh ] || (\
            echo "**--> Execute specific.sh in $(CONFIG_GUESS)/" && \
            cd $(CONFIG_GUESS) && ./specific.sh )
+       @echo "----> Cleaning .svn metadata directories"
+       @find $(DISTDIR) -type d -name ".svn" | xargs rm -fr
 
 pkg: install
        @echo "----> Create distribution file $(BLENDNAME)$(EXT1)"
index 0209b04844a018f6e4a7ca91fd5a6697f8388f6c..54e1ea3db331c39853c5f35c5c96d3da3cf70802 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """ 
 Name: '3D Studio (.3ds)...'
 Blender: 243
index 105112e6ec364c8d83ace411b52e14edd819965a..063c6380483e48e0795d0529ed9db40cf5cf242f 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """ Registration info for Blender menus
 Name: 'Bevel Center'
 Blender: 243
index ef765086e2588184f5cc3b8d1cb52d100b447414..c4815811512d982916e0a74eca199ba332106eae 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """
 Name: 'BlenderLipSynchro'
 Blender: 242
index bd3ee845d21cd467eb230534dad2c9f194e1302c..ef42eab9e8fe23f98644f39c2e6b789ac4e5bc4e 100644 (file)
@@ -68,11 +68,7 @@ def add_mesh_simple(name, verts, edges, faces):
                else:
                        # Mesh with no data, unlikely
                        me.edges.extend(edges)
-                       me.faces.extend(faces)
-
-               if is_editmode or Blender.Get('add_editmode'):
-                       EditMode(1)
-               
+                       me.faces.extend(faces)          
        else:
                
                # Object mode add new
@@ -95,9 +91,13 @@ def add_mesh_simple(name, verts, edges, faces):
                        ob_act.setMatrix(mat)
                
                ob_act.loc = cursor
-
-               if is_editmode or Blender.Get('add_editmode'):
-                       EditMode(1)
+       
+       if is_editmode or Blender.Get('add_editmode'):
+               EditMode(1)
+       else: # adding in object mode means we need to calc normals
+               me.calcNormals()
+               
+                       
 
 
 def write_mesh_script(filepath, me):
@@ -112,7 +112,7 @@ def write_mesh_script(filepath, me):
        file.write('#!BPY\n')
        file.write('"""\n')
        file.write('Name: \'%s\'\n' % name)
-       file.write('Blender: 243\n')
+       file.write('Blender: 245\n')
        file.write('Group: \'AddMesh\'\n')
        file.write('"""\n\n')
        file.write('import BPyAddMesh\n')
index d4a39cf63d6b21355ad24887159b5e4971995d55..df4ebc309e4f55f97e52378620c6054f6b8a20d3 100644 (file)
@@ -1,11 +1,12 @@
 """This module provides a function for reading dxf files and parsing them into a useful tree of objects and data.
 
-    The convert function is called by the readDXF fuction to convert dxf strings into the correct data based 
-    on their type code.  readDXF expects a (full path) file name as input.
+       The convert function is called by the readDXF fuction to convert dxf strings into the correct data based
+       on their type code.  readDXF expects a (full path) file name as input.
 """
 
 # --------------------------------------------------------------------------
 # DXF Reader v0.9 by Ed Blake (AKA Kitsu)
+#  2008.05.08 modif.def convert() by Remigiusz Fiedler (AKA migius)
 # --------------------------------------------------------------------------
 # ***** BEGIN GPL LICENSE BLOCK *****
 #
 #from dxfImportObjects import *
 
 class Object:
-    """Empty container class for dxf objects"""
-    
-    def __init__(self, _type='', block=False):
-        """_type expects a string value."""
-        self.type = _type
-        self.name = ''
-        self.data = []
-    
-    def __str__(self):
-        if self.name:
-            return self.name
-        else:
-            return self.type
-    
-    def __repr__(self):
-        return str(self.data)
-    
-    def get_type(self, kind=''):
-        """Despite the name, this method actually returns all objects of type 'kind' from self.data."""
-        if type:
-            objects = []
-            for item in self.data:
-                if type(item) != list and item.type == kind:
-                    # we want this type of object
-                    objects.append(item)
-                elif type(item) == list and item[0] == kind:
-                    # we want this type of data
-                    objects.append(item[1])
-            return objects
-    
+       """Empty container class for dxf objects"""
+
+       def __init__(self, _type='', block=False):
+               """_type expects a string value."""
+               self.type = _type
+               self.name = ''
+               self.data = []
+
+       def __str__(self):
+               if self.name:
+                       return self.name
+               else:
+                       return self.type
+
+       def __repr__(self):
+               return str(self.data)
+
+       def get_type(self, kind=''):
+               """Despite the name, this method actually returns all objects of type 'kind' from self.data."""
+               if type:
+                       objects = []
+                       for item in self.data:
+                               if type(item) != list and item.type == kind:
+                                       # we want this type of object
+                                       objects.append(item)
+                               elif type(item) == list and item[0] == kind:
+                                       # we want this type of data
+                                       objects.append(item[1])
+                       return objects
+
 
 class InitializationError(Exception): pass
 
 class StateMachine:
-    """(finite) State Machine from the great David Mertz's great Charming Python article."""
-    
-    def __init__(self):
-        self.handlers = []
-        self.startState = None
-        self.endStates = []
-            
-    def add_state(self, handler, end_state=0):
-        """All states and handlers are functions which return
-        a state and a cargo."""
-        self.handlers.append(handler)
-        if end_state:
-            self.endStates.append(handler)    
-    def set_start(self, handler):
-        """Sets the starting handler function."""
-        self.startState = handler
-    
-    
-    def run(self, cargo=None):
-        if not self.startState:
-            raise InitializationError,\
-                  "must call .set_start() before .run()"
-        if not self.endStates:
-            raise InitializationError, \
-                  "at least one state must be an end_state"
-        handler = self.startState
-        while 1:
-            (newState, cargo) = handler(cargo)
-            #print cargo
-            if newState in self.endStates:
-                return newState(cargo)
-                #break
-            elif newState not in self.handlers:
-                raise RuntimeError, "Invalid target %s" % newState
-            else:
-                handler = newState
+       """(finite) State Machine from the great David Mertz's great Charming Python article."""
+
+       def __init__(self):
+               self.handlers = []
+               self.startState = None
+               self.endStates = []
+
+       def add_state(self, handler, end_state=0):
+               """All states and handlers are functions which return
+               a state and a cargo."""
+               self.handlers.append(handler)
+               if end_state:
+                       self.endStates.append(handler)
+       def set_start(self, handler):
+               """Sets the starting handler function."""
+               self.startState = handler
+
+
+       def run(self, cargo=None):
+               if not self.startState:
+                       raise InitializationError,\
+                                 "must call .set_start() before .run()"
+               if not self.endStates:
+                       raise InitializationError, \
+                                 "at least one state must be an end_state"
+               handler = self.startState
+               while 1:
+                       (newState, cargo) = handler(cargo)
+                       #print cargo
+                       if newState in self.endStates:
+                               return newState(cargo)
+                               #break
+                       elif newState not in self.handlers:
+                               raise RuntimeError, "Invalid target %s" % newState
+                       else:
+                               handler = newState
 
 def get_name(data):
-    """Get the name of an object from its object data.
-    
-    Returns a pair of (data_item, name) where data_item is the list entry where the name was found
-    (the data_item can be used to remove the entry from the object data).  Be sure to check 
-    name not None before using the returned values!
-    """
-    value = None
-    for item in data:
-        if item[0] == 2:
-            value = item[1]
-            break
-    return item, value
+       """Get the name of an object from its object data.
+
+       Returns a pair of (data_item, name) where data_item is the list entry where the name was found
+       (the data_item can be used to remove the entry from the object data).  Be sure to check
+       name not None before using the returned values!
+       """
+       value = None
+       for item in data:
+               if item[0] == 2:
+                       value = item[1]
+                       break
+       return item, value
 
 def get_layer(data):
-    """Expects object data as input.
-    
-    Returns (entry, layer_name) where entry is the data item that provided the layer name.
-    """
-    value = None
-    for item in data:
-        if item[0] == 8:
-            value = item[1]
-            break
-    return item, value
+       """Expects object data as input.
+
+       Returns (entry, layer_name) where entry is the data item that provided the layer name.
+       """
+       value = None
+       for item in data:
+               if item[0] == 8:
+                       value = item[1]
+                       break
+       return item, value
 
 
 def convert(code, value):
-    """Convert a string to the correct Python type based on its dxf code.
-    code types:
-        ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070
-        longs = 90-99, 420-429, 440-459, 1071
-        floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059
-        hex = 105, 310-379, 390-399
-        strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009
-    """
-    if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071:
-        value = int(value)
-    elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071:
-        value = long(value)
-    elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060:
-        value = float(value)
-    elif code == 105 or 309 < code < 380 or 389 < code < 400:
-        value = int(value, 16) # should be left as string?
-    else: # it's already a string so do nothing
-        pass
-    return value
+       """Convert a string to the correct Python type based on its dxf code.
+       code types:
+               ints = 60-79, 170-179, 270-289, 370-389, 400-409, 1060-1070
+               longs = 90-99, 420-429, 440-459, 1071
+               floats = 10-39, 40-59, 110-139, 140-149, 210-239, 460-469, 1010-1059
+               hex = 105, 310-379, 390-399
+               strings = 0-9, 100, 102, 300-309, 410-419, 430-439, 470-479, 999, 1000-1009
+       """
+       if 59 < code < 80 or 169 < code < 180 or 269 < code < 290 or 369 < code < 390 or 399 < code < 410 or 1059 < code < 1071:
+               value = int(float(value))
+       elif 89 < code < 100 or 419 < code < 430 or 439 < code < 460 or code == 1071:
+               value = long(float(value))
+       elif 9 < code < 60 or 109 < code < 150 or 209 < code < 240 or 459 < code < 470 or 1009 < code < 1060:
+               value = float(value)
+       elif code == 105 or 309 < code < 380 or 389 < code < 400:
+               value = int(value, 16) # should be left as string?
+       else: # it's already a string so do nothing
+               pass
+       return value
 
 
 def findObject(infile, kind=''):
-    """Finds the next occurance of an object."""
-    obj = False
-    while 1:
-        line = infile.readline()
-        if not line: # readline returns '' at eof
-            return False
-        if not obj: # We're still looking for our object code
-            if line.lower().strip() == '0':
-                obj = True # found it
-        else: # we are in an object definition
-            if kind: # if we're looking for a particular kind
-                if line.lower().strip() == kind:
-                    obj = Object(line.lower().strip())
-                    break
-            else: # otherwise take anything non-numeric
-                if line.lower().strip() not in string.digits:
-                    obj = Object(line.lower().strip())
-                    break
-            obj = False # whether we found one or not it's time to start over
-    return obj
+       """Finds the next occurance of an object."""
+       obj = False
+       while 1:
+               line = infile.readline()
+               if not line: # readline returns '' at eof
+                       return False
+               if not obj: # We're still looking for our object code
+                       if line.lower().strip() == '0':
+                               obj = True # found it
+               else: # we are in an object definition
+                       if kind: # if we're looking for a particular kind
+                               if line.lower().strip() == kind:
+                                       obj = Object(line.lower().strip())
+                                       break
+                       else: # otherwise take anything non-numeric
+                               if line.lower().strip() not in string.digits:
+                                       obj = Object(line.lower().strip())
+                                       break
+                       obj = False # whether we found one or not it's time to start over
+       return obj
 
 def handleObject(infile):
-    """Add data to an object until end of object is found."""
-    line = infile.readline()
-    if line.lower().strip() == 'section':
-        return 'section' # this would be a problem
-    elif line.lower().strip() == 'endsec':
-        return 'endsec' # this means we are done with a section
-    else: # add data to the object until we find a new object
-        obj = Object(line.lower().strip())
-        obj.name = obj.type
-        done = False
-        data = []
-        while not done:
-            line = infile.readline()
-            if not data:
-                if line.lower().strip() == '0':
-                    #we've found an object, time to return
-                    return obj
-                else:
-                    # first part is always an int
-                    data.append(int(line.lower().strip()))
-            else:
-                data.append(convert(data[0], line.strip()))
-                obj.data.append(data)
-                data = []
+       """Add data to an object until end of object is found."""
+       line = infile.readline()
+       if line.lower().strip() == 'section':
+               return 'section' # this would be a problem
+       elif line.lower().strip() == 'endsec':
+               return 'endsec' # this means we are done with a section
+       else: # add data to the object until we find a new object
+               obj = Object(line.lower().strip())
+               obj.name = obj.type
+               done = False
+               data = []
+               while not done:
+                       line = infile.readline()
+                       if not data:
+                               if line.lower().strip() == '0':
+                                       #we've found an object, time to return
+                                       return obj
+                               else:
+                                       # first part is always an int
+                                       data.append(int(line.lower().strip()))
+                       else:
+                               data.append(convert(data[0], line.strip()))
+                               obj.data.append(data)
+                               data = []
 
 def handleTable(table, infile):
-    """Special handler for dealing with nested table objects."""
-    item, name = get_name(table.data)
-    if name: # We should always find a name
-        table.data.remove(item)
-        table.name = name.lower()
-    # This next bit is from handleObject
-    # handleObject should be generalized to work with any section like object
-    while 1:
-        obj = handleObject(infile)
-        if obj.type == 'table':
-            print "Warning: previous table not closed!"
-            return table
-        elif obj.type == 'endtab':
-            return table # this means we are done with the table
-        else: # add objects to the table until one of the above is found
-            table.data.append(obj)
-        
-    
-    
+       """Special handler for dealing with nested table objects."""
+       item, name = get_name(table.data)
+       if name: # We should always find a name
+               table.data.remove(item)
+               table.name = name.lower()
+       # This next bit is from handleObject
+       # handleObject should be generalized to work with any section like object
+       while 1:
+               obj = handleObject(infile)
+               if obj.type == 'table':
+                       print "Warning: previous table not closed!"
+                       return table
+               elif obj.type == 'endtab':
+                       return table # this means we are done with the table
+               else: # add objects to the table until one of the above is found
+                       table.data.append(obj)
+
+
+
 
 def handleBlock(block, infile):
-    """Special handler for dealing with nested table objects."""
-    item, name = get_name(block.data)
-    if name: # We should always find a name
-        block.data.remove(item)
-        block.name = name
-    # This next bit is from handleObject
-    # handleObject should be generalized to work with any section like object
-    while 1:
-        obj = handleObject(infile)
-        if obj.type == 'block':
-            print "Warning: previous block not closed!"
-            return block
-        elif obj.type == 'endblk':
-            return block # this means we are done with the table
-        else: # add objects to the table until one of the above is found
-            block.data.append(obj)
-        
-    
-    
+       """Special handler for dealing with nested table objects."""
+       item, name = get_name(block.data)
+       if name: # We should always find a name
+               block.data.remove(item)
+               block.name = name
+       # This next bit is from handleObject
+       # handleObject should be generalized to work with any section like object
+       while 1:
+               obj = handleObject(infile)
+               if obj.type == 'block':
+                       print "Warning: previous block not closed!"
+                       return block
+               elif obj.type == 'endblk':
+                       return block # this means we are done with the table
+               else: # add objects to the table until one of the above is found
+                       block.data.append(obj)
+
+
+
 
 """These are the states/functions used in the State Machine.
 states:
@@ -250,133 +251,131 @@ states:
 """
 
 def start(cargo):
-    """Expects the infile as cargo, initializes the cargo."""
-    #print "Entering start state!"
-    infile = cargo
-    drawing = Object('drawing')
-    section = findObject(infile, 'section')
-    if section:
-        return start_section, (infile, drawing, section)
-    else:
-        return error, (infile, "Failed to find any sections!")
+       """Expects the infile as cargo, initializes the cargo."""
+       #print "Entering start state!"
+       infile = cargo
+       drawing = Object('drawing')
+       section = findObject(infile, 'section')
+       if section:
+               return start_section, (infile, drawing, section)
+       else:
+               return error, (infile, "Failed to find any sections!")
 
 def start_section(cargo):
-    """Expects [infile, drawing, section] as cargo, builds a nested section object."""
-    #print "Entering start_section state!"
-    infile = cargo[0]
-    drawing = cargo[1]
-    section = cargo[2]
-    # read each line, if it is an object declaration go to object mode
-    # otherwise create a [index, data] pair and add it to the sections data.
-    done = False
-    data = []
-    while not done:
-        line = infile.readline()
-        
-        if not data: # if we haven't found a dxf code yet
-            if line.lower().strip() == '0':
-                # we've found an object
-                while 1: # no way out unless we find an end section or a new section
-                    obj = handleObject(infile)
-                    if obj == 'section': # shouldn't happen
-                        print "Warning: failed to close previous section!"
-                        return end_section, (infile, drawing)
-                    elif obj == 'endsec': # This section is over, look for the next
-                        drawing.data.append(section)
-                        return end_section, (infile, drawing)
-                    elif obj.type == 'table': # tables are collections of data
-                        obj = handleTable(obj, infile) # we need to find all there contents
-                        section.data.append(obj) # before moving on
-                    elif obj.type == 'block': # the same is true of blocks
-                        obj = handleBlock(obj, infile) # we need to find all there contents
-                        section.data.append(obj) # before moving on
-                    else: # found another sub-object
-                        section.data.append(obj)                    
-            else:
-                data.append(int(line.lower().strip()))
-        else: # we have our code, now we just need to convert the data and add it to our list.
-            data.append(convert(data[0], line.strip()))
-            section.data.append(data)
-            data = []
+       """Expects [infile, drawing, section] as cargo, builds a nested section object."""
+       #print "Entering start_section state!"
+       infile = cargo[0]
+       drawing = cargo[1]
+       section = cargo[2]
+       # read each line, if it is an object declaration go to object mode
+       # otherwise create a [index, data] pair and add it to the sections data.
+       done = False
+       data = []
+       while not done:
+               line = infile.readline()
+
+               if not data: # if we haven't found a dxf code yet
+                       if line.lower().strip() == '0':
+                               # we've found an object
+                               while 1: # no way out unless we find an end section or a new section
+                                       obj = handleObject(infile)
+                                       if obj == 'section': # shouldn't happen
+                                               print "Warning: failed to close previous section!"
+                                               return end_section, (infile, drawing)
+                                       elif obj == 'endsec': # This section is over, look for the next
+                                               drawing.data.append(section)
+                                               return end_section, (infile, drawing)
+                                       elif obj.type == 'table': # tables are collections of data
+                                               obj = handleTable(obj, infile) # we need to find all there contents
+                                               section.data.append(obj) # before moving on
+                                       elif obj.type == 'block': # the same is true of blocks
+                                               obj = handleBlock(obj, infile) # we need to find all there contents
+                                               section.data.append(obj) # before moving on
+                                       else: # found another sub-object
+                                               section.data.append(obj)
+                       else:
+                               data.append(int(line.lower().strip()))
+               else: # we have our code, now we just need to convert the data and add it to our list.
+                       data.append(convert(data[0], line.strip()))
+                       section.data.append(data)
+                       data = []
 def end_section(cargo):
-    """Expects (infile, drawing) as cargo, searches for next section."""
-    #print "Entering end_section state!"
-    infile = cargo[0]
-    drawing = cargo[1]
-    section = findObject(infile, 'section')
-    if section:
-        return start_section, (infile, drawing, section)
-    else:
-        return end, (infile, drawing)
+       """Expects (infile, drawing) as cargo, searches for next section."""
+       #print "Entering end_section state!"
+       infile = cargo[0]
+       drawing = cargo[1]
+       section = findObject(infile, 'section')
+       if section:
+               return start_section, (infile, drawing, section)
+       else:
+               return end, (infile, drawing)
 
 def end(cargo):
-    """Expects (infile, drawing) as cargo, called when eof has been reached."""
-    #print "Entering end state!"
-    infile = cargo[0]
-    drawing = cargo[1]
-    #infile.close()
-    return drawing
+       """Expects (infile, drawing) as cargo, called when eof has been reached."""
+       #print "Entering end state!"
+       infile = cargo[0]
+       drawing = cargo[1]
+       #infile.close()
+       return drawing
 
 def error(cargo):
-    """Expects a (infile, string) as cargo, called when there is an error during processing."""
-    #print "Entering error state!"
-    infile = cargo[0]
-    err = cargo[1]
-    infile.close()
-    print "There has been an error:"
-    print err
-    return False
+       """Expects a (infile, string) as cargo, called when there is an error during processing."""
+       #print "Entering error state!"
+       infile = cargo[0]
+       err = cargo[1]
+       infile.close()
+       print "There has been an error:"
+       print err
+       return False
 
 def readDXF(filename, objectify):
-    """Given a file name try to read it as a dxf file.
-    
-    Output is an object with the following structure
-    drawing
-        header
-            header data
-        classes
-            class data
-        tables
-            table data
-        blocks
-            block data
-        entities
-            entity data
-        objects
-            object data
-    where foo data is a list of sub-objects.  True object data
-    is of the form [code, data].
-"""
-    infile = open(filename)
-
-    sm = StateMachine()
-    sm.add_state(error, True)
-    sm.add_state(end, True)
-    sm.add_state(start_section)
-    sm.add_state(end_section)
-    sm.add_state(start)
-    sm.set_start(start)
-    try:
-        drawing = sm.run(infile)
-        if drawing:
-            drawing.name = filename
-            for obj in drawing.data:
-                item, name = get_name(obj.data)
-                if name:
-                    obj.data.remove(item)
-                    obj.name = name.lower()
-                    setattr(drawing, name.lower(), obj)
-                    # Call the objectify function to cast
-                    # raw objects into the right types of object
-                    obj.data = objectify(obj.data)
-                #print obj.name
-    finally:
-        infile.close()
-    return drawing    
-if __name__ == "__main__":
-    filename = r".\examples\block-test.dxf"
-    drawing = readDXF(filename)
-    for item in drawing.entities.data:
-        print item
+       """Given a file name try to read it as a dxf file.
 
+       Output is an object with the following structure
+       drawing
+               header
+                       header data
+               classes
+                       class data
+               tables
+                       table data
+               blocks
+                       block data
+               entities
+                       entity data
+               objects
+                       object data
+       where foo data is a list of sub-objects.  True object data
+       is of the form [code, data].
+"""
+       infile = open(filename)
 
+       sm = StateMachine()
+       sm.add_state(error, True)
+       sm.add_state(end, True)
+       sm.add_state(start_section)
+       sm.add_state(end_section)
+       sm.add_state(start)
+       sm.set_start(start)
+       try:
+               drawing = sm.run(infile)
+               if drawing:
+                       drawing.name = filename
+                       for obj in drawing.data:
+                               item, name = get_name(obj.data)
+                               if name:
+                                       obj.data.remove(item)
+                                       obj.name = name.lower()
+                                       setattr(drawing, name.lower(), obj)
+                                       # Call the objectify function to cast
+                                       # raw objects into the right types of object
+                                       obj.data = objectify(obj.data)
+                               #print obj.name
+       finally:
+               infile.close()
+       return drawing
+if __name__ == "__main__":
+       filename = r".\examples\block-test.dxf"
+       drawing = readDXF(filename)
+       for item in drawing.entities.data:
+               print item
index 08215b3d0277e83c38c7cd5e876f60e0f81352ef..86ac03cc407a97134c3a32d41122f097cd7d5bdd 100644 (file)
@@ -1,4 +1,5 @@
 #!BPY
+# coding: utf-8
 """ Registration info for Blender menus:
 Name: 'M3G (.m3g, .java)...'
 Blender: 244
@@ -3069,4 +3070,5 @@ def file_callback_m3g(filename):
     Window.RedrawAll()
     
 if __name__ == '__main__':
-    gui()
\ No newline at end of file
+    gui()
+
index bfaac252b216e7090837e3a0351e5befdd5e6479..929132933ecec3efb2b9da0baebb2881d06d6a01 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """ Registration info for Blender menus:
 Name: 'HotKey and MouseAction Reference'
 Blender: 242
@@ -918,4 +918,4 @@ def bevent(evt):
           Blender.Window.Redraw()
 
 if __name__ == '__main__':
-       Register(draw, event, bevent)
\ No newline at end of file
+       Register(draw, event, bevent)
index 4fa7a6472cfedec670f8ad5c981bba5c347cae34..88b42e3e564d7ffd5eec1e171341cb8c3902331e 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """
 Name: 'Autodesk DXF (.dxf)'
 Blender: 244
@@ -5942,4 +5942,5 @@ if 1:
                        main(_dxf)
 
        print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
-"""
\ No newline at end of file
+"""
+
index c863fdb69629a335605ed81cc1f34baa5e0c5c01..006e97463d83519e7d62d1e7cb2060836e0792f5 100644 (file)
@@ -77,7 +77,11 @@ def copy_vgroups(source_ob, target_ob):
                for vgroupname in vgroups:
                        target_me.addVertGroup(vgroupname)
                        if len(target_me.verts) == len(source_me.verts):
-                               vlist = source_me.getVertsFromGroup(vgroupname, True)
+                               try: # in rare cases this can raise an 'no deform groups assigned to mesh' error
+                                       vlist = source_me.getVertsFromGroup(vgroupname, True)
+                               except:
+                                       vlist = []
+                               
                                try:
                                        for vpair in vlist:
                                                target_me.assignVertsToGroup(vgroupname, [vpair[0]], vpair[1], ADD)
@@ -171,4 +175,4 @@ def apply_deform():
        Blender.Window.RedrawAll()
 
 if __name__=='__main__':
-       apply_deform()
\ No newline at end of file
+       apply_deform()
index 6afb5c8ebba727f31913b0b49ab11b290b0890e1..b35d7fe5c653a05e5187c9ea3d170bec99051391 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """
 Name: 'Paths (.svg, .ps, .eps, .ai, Gimp)'
 Blender: 233
@@ -92,4 +92,5 @@ elif argv=='Gimp_2_0':
   fonctionSELECT = functionSELECT # can they all be called function?
 
 text = 'Import %s' % argv
-Blender.Window.FileSelector (fonctionSELECT, text)
\ No newline at end of file
+Blender.Window.FileSelector (fonctionSELECT, text)
+
index 06f410b97838d02fd67c0b47bd221196be828c2a..ad1265be50c017756bfc29da3e8099670d0346c5 100644 (file)
@@ -47,8 +47,12 @@ rend = sce.render
 
 # default filename: theme's name + '_theme.py' in user's scripts dir:
 default_fname = Blender.Get("scriptsdir")
-default_fname = Blender.sys.join(default_fname, sce.name + '_renderlayer.py')
-default_fname = default_fname.replace(' ','_')
+if not default_fname:
+       default_fname = Blender.Get("uscriptsdir")
+
+if default_fname:
+       default_fname = Blender.sys.join(default_fname, sce.name + '_renderlayer.py')
+       default_fname = default_fname.replace(' ','_')
 
 def write_renderlayers(filename):
        "Write the current renderlayer as a bpython script"
@@ -113,4 +117,4 @@ rend = sce.render
        except:
                Blender.Draw.PupMenu("Warning - check console!%t|Menus could not be automatically updated")
 
-FileSelector(write_renderlayers, "Save RenderLayers", default_fname)
\ No newline at end of file
+FileSelector(write_renderlayers, "Save RenderLayers", default_fname)
index c8d6fe0e741ec10ce013304f9cd90f2cb74b5ae4..c723efb61a7df2e0be3395e3ab850e061a5163d5 100644 (file)
@@ -1,5 +1,5 @@
 #!BPY
-
+# coding: utf-8
 """ Registration info for Blender menus: <- these words are ignored
 Name: 'Deformed mesh to Rvk'
 Blender: 243
@@ -270,4 +270,4 @@ def deform2rvk():
 EDITMODE=Blender.Window.EditMode()
 Blender.Window.EditMode(0)
 deform2rvk()
-Blender.Window.EditMode(EDITMODE)
\ No newline at end of file
+Blender.Window.EditMode(EDITMODE)
index ac4a8e9ca5be2a0d0e3b6acabc70cf4d35f6070b..b12ff67d8a606842d8851cfbce7c506900c910aa 100644 (file)
@@ -57,6 +57,8 @@ import Blender
 from Blender import Object, Lamp, Draw, Image, Text, sys, Mesh
 from Blender.Scene import Render
 import math
+import BPyObject
+import BPyMesh
 
 # 
 DEG2RAD=0.017453292519943295
@@ -68,14 +70,14 @@ MATWORLD= Blender.Mathutils.RotationMatrix(-90, 4, 'x')
 
 filename = Blender.Get('filename')
 _safeOverwrite = True
-ARG=''
+
 extension = ''
 
 ##########################################################
 # Functions for writing output file
 ##########################################################
 
-class VRML2Export:
+class x3d_class:
 
        def __init__(self, filename):
                #--- public you can change these ---
@@ -101,7 +103,18 @@ class VRML2Export:
                self.meshNames={}   # dictionary of meshNames
                self.indentLevel=0 # keeps track of current indenting
                self.filename=filename
-               self.file = open(filename, "w")
+               self.file = None
+               if filename.lower().endswith('.x3dz'):
+                       try:
+                               import gzip
+                               self.file = gzip.open(filename, "w")                            
+                       except:
+                               print "failed to import compression modules, exporting uncompressed"
+                               self.filename = filename[:-1] # remove trailing z
+               
+               if self.file == None:
+                       self.file = open(self.filename, "w")
+
                self.bNav=0
                self.nodeID=0
                self.namesReserved=[ "Anchor","Appearance","Arc2D","ArcClose2D","AudioClip","Background","Billboard",
@@ -169,7 +182,7 @@ class VRML2Export:
                                        nameinline = nameinline+".x3d"
                                        self.file.write("url=\"%s\" />" % nameinline)
                                        self.file.write("\n\n")
-       '''
+
        
        def writeScript(self):
                textEditor = Blender.Text.Get() 
@@ -190,15 +203,17 @@ class VRML2Export:
                                        for j in xrange(nalllines):
                                                self.writeIndented(alllines[j] + "\n")
                self.writeIndented("\n")
-
-       def writeViewpoint(self, ob, scene):
+       '''
+       
+       def writeViewpoint(self, ob, mat, scene):
                context = scene.render
                ratio = float(context.imageSizeY())/float(context.imageSizeX())
                lens = (360* (math.atan(ratio *16 / ob.data.getLens()) / math.pi))*(math.pi/180)
                lens = min(lens, math.pi) 
                
                # get the camera location, subtract 90 degress from X to orient like X3D does
-               mat = ob.matrixWorld
+               # mat = ob.matrixWorld - mat is now passed!
+               
                loc = self.rotatePointForVRML(mat.translationPart())
                rot = mat.toEuler()
                rot = (((rot[0]-90)*DEG2RAD), rot[1]*DEG2RAD, rot[2]*DEG2RAD)
@@ -229,23 +244,11 @@ class VRML2Export:
                        self.file.write("visibilityRange=\"%s\" />\n\n" % round(mparam[2],self.cp))
                else:
                        return
-       '''
+       
        def writeNavigationInfo(self, scene):
-               allObj = []
-               allObj = list(scene.objects)
-               headlight = "true"
-               vislimit = 0.0
-               for ob in allObj:
-                       objType=ob.type
-                       if objType == "Camera":
-                               vislimit = ob.data.clipEnd
-                       elif objType == "Lamp":
-                               headlight = "false"
-               self.file.write("<NavigationInfo headlight=\"%s\" " % headlight)
-               self.file.write("visibilityLimit=\"%s\" " % (round(vislimit,self.cp)))
-               self.file.write("type=\"EXAMINE\", \"ANY\" avatarSize=\"0.25, 1.75, 0.75\" />\n\n")
-       '''
-       def writeSpotLight(self, ob, lamp, world):
+               self.file.write('<NavigationInfo headlight="FALSE" visibilityLimit="0.0" type=\'"EXAMINE","ANY"\' avatarSize="0.25, 1.75, 0.75" />\n')
+       
+       def writeSpotLight(self, ob, mtx, lamp, world):
                safeName = self.cleanStr(ob.name)
                if world:
                        ambi = world.amb
@@ -259,12 +262,14 @@ class VRML2Export:
                beamWidth=((lamp.spotSize*math.pi)/180.0)*.37;
                cutOffAngle=beamWidth*1.3
 
-               dx,dy,dz=self.computeDirection(ob)
+               dx,dy,dz=self.computeDirection(mtx)
                # note -dx seems to equal om[3][0]
                # note -dz seems to equal om[3][1]
                # note  dy seems to equal om[3][2]
 
-               location=(ob.matrixWorld*MATWORLD).translationPart()
+               #location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
+               location=(mtx*MATWORLD).translationPart()
+               
                radius = lamp.dist*math.cos(beamWidth)
                self.file.write("<SpotLight DEF=\"%s\" " % safeName)
                self.file.write("radius=\"%s\" " % (round(radius,self.cp)))
@@ -277,7 +282,7 @@ class VRML2Export:
                self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
                
                
-       def writeDirectionalLight(self, ob, lamp, world):
+       def writeDirectionalLight(self, ob, mtx, lamp, world):
                safeName = self.cleanStr(ob.name)
                if world:
                        ambi = world.amb
@@ -287,14 +292,14 @@ class VRML2Export:
                        ambientIntensity = 0
 
                intensity=min(lamp.energy/1.75,1.0) 
-               (dx,dy,dz)=self.computeDirection(ob)
+               (dx,dy,dz)=self.computeDirection(mtx)
                self.file.write("<DirectionalLight DEF=\"%s\" " % safeName)
                self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
                self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
                self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
                self.file.write("direction=\"%s %s %s\" />\n\n" % (round(dx,4),round(dy,4),round(dz,4)))
 
-       def writePointLight(self, ob, lamp, world):
+       def writePointLight(self, ob, mtx, lamp, world):
                safeName = self.cleanStr(ob.name)
                if world:
                        ambi = world.amb
@@ -303,29 +308,30 @@ class VRML2Export:
                        ambi = 0
                        ambientIntensity = 0
                
-               location=(ob.matrixWorld*MATWORLD).translationPart()
-               intensity=min(lamp.energy/1.75,1.0) 
-               radius = lamp.dist
+               # location=(ob.matrixWorld*MATWORLD).translationPart() # now passed
+               location= (mtx*MATWORLD).translationPart()
+               
                self.file.write("<PointLight DEF=\"%s\" " % safeName)
                self.file.write("ambientIntensity=\"%s\" " % (round(ambientIntensity,self.cp)))
                self.file.write("color=\"%s %s %s\" " % (round(lamp.col[0],self.cp), round(lamp.col[1],self.cp), round(lamp.col[2],self.cp)))
-               self.file.write("intensity=\"%s\" " % (round(intensity,self.cp)))
-               self.file.write("radius=\"%s\" " % radius )
+               self.file.write("intensity=\"%s\" " % (round( min(lamp.energy/1.75,1.0) ,self.cp)))
+               self.file.write("radius=\"%s\" " % lamp.dist )
                self.file.write("location=\"%s %s %s\" />\n\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
-
-       def writeNode(self, ob):
+       '''
+       def writeNode(self, ob, mtx):
                obname=str(ob.name)
                if obname in self.namesStandard:
                        return
                else:
-                       dx,dy,dz = self.computeDirection(ob)
-                       location=(ob.matrixWorld*MATWORLD).translationPart()
+                       dx,dy,dz = self.computeDirection(mtx)
+                       # location=(ob.matrixWorld*MATWORLD).translationPart()
+                       location=(mtx*MATWORLD).translationPart()
                        self.writeIndented("<%s\n" % obname,1)
-                       self.writeIndented("# direction %s %s %s\n" % (round(dx,3),round(dy,3),round(dz,3)))
-                       self.writeIndented("# location %s %s %s\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
+                       self.writeIndented("direction=\"%s %s %s\"\n" % (round(dx,3),round(dy,3),round(dz,3)))
+                       self.writeIndented("location=\"%s %s %s\"\n" % (round(location[0],3), round(location[1],3), round(location[2],3)))
                        self.writeIndented("/>\n",-1)
                        self.writeIndented("\n")
-
+       '''
        def secureName(self, name):
                name = name + str(self.nodeID)
                self.nodeID=self.nodeID+1
@@ -345,13 +351,13 @@ class VRML2Export:
                                newname = name
                                return "%s" % (newname)
 
-       def writeIndexedFaceSet(self, ob, world, normals = 0):
+       def writeIndexedFaceSet(self, ob, mesh, mtx, world, EXPORT_TRI = False):
                imageMap={}   # set of used images
                sided={}          # 'one':cnt , 'two':cnt
                vColors={}      # 'multi':1
                meshName = self.cleanStr(ob.name)
-               mesh=ob.getData(mesh=1)
-               meshME = self.cleanStr(mesh.name)
+               
+               meshME = self.cleanStr(ob.getData(mesh=1).name) # We dont care if its the mesh name or not
                if len(mesh.faces) == 0: return
                mode = 0
                if mesh.faceUV:
@@ -371,7 +377,7 @@ class VRML2Export:
                elif not mode & Mesh.FaceModes.DYNAMIC and self.collnode == 0:
                        self.writeIndented("<Collision enabled=\"false\">\n",1)
                        self.collnode = 1
-
+               
                nIFSCnt=self.countIFSSetsNeeded(mesh, imageMap, sided, vColors)
                
                if nIFSCnt > 1:
@@ -382,7 +388,8 @@ class VRML2Export:
                else:
                        bTwoSided=0
 
-               mtx = ob.matrixWorld * MATWORLD
+               # mtx = ob.matrixWorld * MATWORLD # mtx is now passed
+               mtx = mtx * MATWORLD
                
                loc= mtx.translationPart()
                sca= mtx.scalePart()
@@ -456,12 +463,12 @@ class VRML2Export:
                                elif hasImageTexture == 1:
                                        self.writeTextureCoordinates(mesh)
                        #--- output coordinates
-                       self.writeCoordinates(ob, mesh, meshName)
+                       self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
 
                        self.writingcoords = 1
                        self.writingtexture = 1
                        self.writingcolor = 1
-                       self.writeCoordinates(ob, mesh, meshName)
+                       self.writeCoordinates(ob, mesh, meshName, EXPORT_TRI)
                        
                        #--- output textureCoordinates if UV texture used
                        if mesh.faceUV:
@@ -498,17 +505,23 @@ class VRML2Export:
 
                self.file.write("\n")
 
-       def writeCoordinates(self, ob, mesh, meshName):
+       def writeCoordinates(self, ob, mesh, meshName, EXPORT_TRI = False):
                # create vertex list and pre rotate -90 degrees X for VRML
                
                if self.writingcoords == 0:
                        self.file.write('coordIndex="')
                        for face in mesh.faces:
                                fv = face.v
-                               if len(face)==4:
-                                       self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
+                               
+                               if len(face)==3:
+                                               self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
                                else:
-                                       self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+                                       if EXPORT_TRI:
+                                               self.file.write("%i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index))
+                                               self.file.write("%i %i %i -1, " % (fv[0].index, fv[2].index, fv[3].index))
+                                       else:
+                                               self.file.write("%i %i %i %i -1, " % (fv[0].index, fv[1].index, fv[2].index, fv[3].index))
+                       
                        self.file.write("\">\n")
                else:
                        #-- vertices
@@ -679,43 +692,74 @@ class VRML2Export:
 # export routine
 ##########################################################
 
-       def export(self, scene, world, alltextures):
+       def export(self, scene, world, alltextures,\
+                       EXPORT_APPLY_MODIFIERS = False,\
+                       EXPORT_TRI=                             False,\
+               ):
+               
                print "Info: starting X3D export to " + self.filename + "..."
                self.writeHeader()
-               self.writeScript()
-               # self.writeNavigationInfo(scene) # This seems to position me in some strange area I cant see the model (with BS Contact) - Campbell
+               self.writeScript()
+               self.writeNavigationInfo(scene)
                self.writeBackground(world, alltextures)
                self.writeFog(world)
                self.proto = 0
                
-               for ob in scene.objects.context:
-                       objType=ob.type
-                       objName=ob.name
-                       self.matonly = 0
-                       if objType == "Camera":
-                               self.writeViewpoint(ob, scene)
-                       elif objType == "Mesh":
-                               self.writeIndexedFaceSet(ob, world, normals = 0)
-                       elif objType == "Lamp":
-                               data= ob.data
-                               datatype=data.type
-                               if datatype == Lamp.Types.Lamp:
-                                       self.writePointLight(ob, data, world)
-                               elif datatype == Lamp.Types.Spot:
-                                       self.writeSpotLight(ob, data, world)
-                               elif datatype == Lamp.Types.Sun:
-                                       self.writeDirectionalLight(ob, data, world)
+               
+               # COPIED FROM OBJ EXPORTER
+               if EXPORT_APPLY_MODIFIERS:
+                       temp_mesh_name = '~tmp-mesh'
+               
+                       # Get the container mesh. - used for applying modifiers and non mesh objects.
+                       containerMesh = meshName = tempMesh = None
+                       for meshName in Blender.NMesh.GetNames():
+                               if meshName.startswith(temp_mesh_name):
+                                       tempMesh = Mesh.Get(meshName)
+                                       if not tempMesh.users:
+                                               containerMesh = tempMesh
+                       if not containerMesh:
+                               containerMesh = Mesh.New(temp_mesh_name)
+               # -------------------------- 
+               
+               
+               for ob_main in scene.objects.context:
+                       for ob, ob_mat in BPyObject.getDerivedObjects(ob_main):
+                               objType=ob.type
+                               objName=ob.name
+                               self.matonly = 0
+                               if objType == "Camera":
+                                       self.writeViewpoint(ob, ob_mat, scene)
+                               elif objType in ("Mesh", "Curve", "Surf", "Text") :
+                                       if  EXPORT_APPLY_MODIFIERS or objType != 'Mesh':
+                                               me= BPyMesh.getMeshFromObject(ob, containerMesh, EXPORT_APPLY_MODIFIERS, False, scene)
+                                       else:
+                                               me = ob.getData(mesh=1)
+                                       
+                                       self.writeIndexedFaceSet(ob, me, ob_mat, world, EXPORT_TRI = EXPORT_TRI)
+                               elif objType == "Lamp":
+                                       data= ob.data
+                                       datatype=data.type
+                                       if datatype == Lamp.Types.Lamp:
+                                               self.writePointLight(ob, ob_mat, data, world)
+                                       elif datatype == Lamp.Types.Spot:
+                                               self.writeSpotLight(ob, ob_mat, data, world)
+                                       elif datatype == Lamp.Types.Sun:
+                                               self.writeDirectionalLight(ob, ob_mat, data, world)
+                                       else:
+                                               self.writeDirectionalLight(ob, ob_mat, data, world)
+                               # do you think x3d could document what to do with dummy objects?
+                               #elif objType == "Empty" and objName != "Empty":
+                               #       self.writeNode(ob, ob_mat)
                                else:
-                                       self.writeDirectionalLight(ob, data, world)
-                       elif objType == "Empty" and objName != "Empty":
-                               self.writeNode(ob)
-                       else:
-                               #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
-                               print ""
+                                       #print "Info: Ignoring [%s], object type [%s] not handle yet" % (object.name,object.getType)
+                                       pass
                
-               if ARG != 'selected':
-                       self.writeScript()
                self.file.write("\n</Scene>\n</X3D>")
+               
+               if EXPORT_APPLY_MODIFIERS:
+                       if containerMesh:
+                               containerMesh.verts = None
+               
                self.cleanup()
                
 ##########################################################
@@ -837,10 +881,10 @@ class VRML2Export:
                        round(c.b/255.0,self.cp))
                return s
 
-       def computeDirection(self, ob):
+       def computeDirection(self, mtx):
                x,y,z=(0,-1.0,0) # point down
                
-               ax,ay,az = (ob.matrixWorld*MATWORLD).toEuler()
+               ax,ay,az = (mtx*MATWORLD).toEuler()
                
                ax *= DEG2RAD
                ay *= DEG2RAD
@@ -931,7 +975,36 @@ class VRML2Export:
 # Callbacks, needed before Main
 ##########################################################
 
-def select_file(filename):
+def x3d_export(filename, \
+               EXPORT_APPLY_MODIFIERS= False,\
+               EXPORT_TRI=                             False,\
+               EXPORT_GZIP=                    False,\
+       ):
+       
+       if EXPORT_GZIP:
+               if not filename.lower().endswith('.x3dz'):
+                       filename = '.'.join(filename.split('.')[:-1]) + '.x3dz'
+       else:
+               if not filename.lower().endswith('.x3d'):
+                       filename = '.'.join(filename.split('.')[:-1]) + '.x3d'
+       
+       
+       scene = Blender.Scene.GetCurrent()
+       world = scene.world
+       alltextures = Blender.Texture.Get()
+
+       wrlexport=x3d_class(filename)
+       wrlexport.export(\
+               scene,\
+               world,\
+               alltextures,\
+               \
+               EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS,\
+               EXPORT_TRI = EXPORT_TRI,\
+               )
+
+
+def x3d_export_ui(filename):
        if not filename.endswith(extension):
                filename += extension
        #if _safeOverwrite and sys.exists(filename):
@@ -939,18 +1012,40 @@ def select_file(filename):
        #if(result != 1):
        #       return
        
-       scene = Blender.Scene.GetCurrent()
-       world = scene.world
-       alltextures = Blender.Texture.Get()
+       # Get user options
+       EXPORT_APPLY_MODIFIERS = Draw.Create(1)
+       EXPORT_TRI = Draw.Create(0)
+       EXPORT_GZIP = Draw.Create( filename.lower().endswith('.x3dz') )
+       
+       # Get USER Options
+       pup_block = [\
+       ('Apply Modifiers', EXPORT_APPLY_MODIFIERS, 'Use transformed mesh data from each object.'),\
+       ('Triangulate', EXPORT_TRI, 'Triangulate quads.'),\
+       ('Compress', EXPORT_GZIP, 'GZip the resulting file, requires a full python install'),\
+       ]
+
+       if not Draw.PupBlock('Export...', pup_block):
+               return
+
+       Blender.Window.EditMode(0)
+       Blender.Window.WaitCursor(1)
+       
+       x3d_export(filename,\
+               EXPORT_APPLY_MODIFIERS = EXPORT_APPLY_MODIFIERS.val,\
+               EXPORT_TRI = EXPORT_TRI.val,\
+               EXPORT_GZIP = EXPORT_GZIP.val\
+       )
+       
+       Blender.Window.WaitCursor(0)
 
-       wrlexport=VRML2Export(filename)
-       wrlexport.export(scene, world, alltextures)
 
 
 #########################################################
 # main routine
 #########################################################
 
+
 if __name__ == '__main__':
-       Blender.Window.FileSelector(select_file,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
-       # select_file('/shared/bed1.x3d')
+       Blender.Window.FileSelector(x3d_export_ui,"Export X3D", Blender.Get('filename').replace('.blend', '.x3d'))
+
+
index 9d3a7da89be3cac53d1031803314732a432d32cf..cd8bf0e7cb47a23c2345980f3ce88189f07447bc 100644 (file)
@@ -317,12 +317,10 @@ ifeq ($(WITH_BF_BLENDERPLAYER), true)
 endif
 
 ifeq ($(WITH_BF_WEBPLUGIN), true)
-    ifneq ($(NAN_NO_PLUGIN), true)
-        BINTARGETS += plugin
-        ifeq ($(OS),linux)
-            ifeq ($(CPU),i386)
-                 BINTARGETS += xplink
-             endif
+    BINTARGETS += plugin
+    ifeq ($(OS),linux)
+        ifeq ($(CPU),i386)
+             BINTARGETS += xplink
         endif
     endif
 endif
index 46252b310aefd64fec0d7a5041305100dbe652bb..2d7d0e9286fceda6c1a1c8c83a6d7ac3ebf66da5 100644 (file)
@@ -171,4 +171,9 @@ void IDP_FreeProperty(struct IDProperty *prop);
 /*Unlinks any struct IDProperty<->ID linkage that might be going on.*/
 void IDP_UnlinkProperty(struct IDProperty *prop);
 
+#define IDP_Int(prop) (prop->data.val)
+#define IDP_Float(prop) (*(float*)&prop->data.val)
+#define IDP_String(prop) ((char*)prop->data.pointer)
+#define IDP_Array(prop) (prop->data.pointer)
+
 #endif /* _BKE_IDPROP_H */
index 844f25d51dc998ca01e3d621ff3c0840796a4c6a..7819919fba888e4b8ec4ca40ddd25ff887cb3662 100644 (file)
@@ -43,6 +43,7 @@ extern "C" {
 #define FFMPEG_H264     6
 #define FFMPEG_XVID     7
 #define FFMPEG_FLV      8
+#define FFMPEG_MKV      9
 
 #define FFMPEG_CODEC_MPEG1 0
 #define FFMPEG_CODEC_MPEG2 1
@@ -58,6 +59,7 @@ extern "C" {
 #define FFMPEG_PRESET_SVCD 2
 #define FFMPEG_PRESET_VCD  3
 #define FFMPEG_PRESET_DV   4
+#define FFMPEG_PRESET_H264 5
 
 struct RenderData;     
 
index 8533175ad37f2d2a8e783df143f59584aa6886ca..974754968656a4def51f9474502fd0b29f3e6182 100644 (file)
@@ -337,6 +337,7 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
 {
        extern int enable_cu_speed;     /* object.c */
        Object copyob;
+       DupliObject *dob;
        int cfrao, ok;
        
        /* simple preventing of too deep nested groups */
@@ -360,7 +361,8 @@ static void frames_duplilist(ListBase *lb, Object *ob, int level, int animated)
                if(ok) {
                        do_ob_ipo(ob);
                        where_is_object_time(ob, (float)G.scene->r.cfra);
-                       new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated);
+                       dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, G.scene->r.cfra, OB_DUPLIFRAMES, animated);
+                       Mat4CpyMat4(dob->omat, copyob.obmat);
                }
        }
 
@@ -723,7 +725,7 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
 static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level, int animated)
 {
        GroupObject *go;
-       Object *ob=0, **oblist=0;
+       Object *ob=0, **oblist=0, obcopy, *obcopylist=0;
        DupliObject *dob;
        ParticleSettings *part;
        ParticleData *pa;
@@ -733,7 +735,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
        ParticleSystemModifierData *psmd;
        float ctime, pa_time, scale = 1.0f;
        float tmat[4][4], mat[4][4], obrotmat[4][4], pamat[4][4], size=0.0;
-       float (*obmat)[4];
+       float (*obmat)[4], (*oldobmat)[4];
        float xvec[3] = {-1.0, 0.0, 0.0}, q[4];
        int lay, a, b, k, step_nbr = 0, counter, hair = 0;
        int totpart, totchild, totgroup=0, pa_num;
@@ -758,7 +760,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
        totchild = psys->totchild;
 
        BLI_srandom(31415926 + psys->seed);
-               
+       
        lay= G.scene->lay;
        if((part->draw_as == PART_DRAW_OB && part->dup_ob) ||
                (part->draw_as == PART_DRAW_GR && part->dup_group && part->dup_group->gobject.first)) {
@@ -778,49 +780,55 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
 
                psys->lattice = psys_get_lattice(par, psys);
 
+               /* gather list of objects or single object */
                if(part->draw_as==PART_DRAW_GR) {
                        group_handle_recalc_and_update(par, part->dup_group);
 
-                       go= part->dup_group->gobject.first;
-                       while(go) {
-                               go=go->next;
+                       for(go=part->dup_group->gobject.first; go; go=go->next)
                                totgroup++;
-                       }
 
-                       oblist= MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
-                       go= part->dup_group->gobject.first;
-                       for(a=0; a<totgroup; a++, go=go->next)
-                               oblist[a]=go->ob;
+                       /* we also copy the actual objects to restore afterwards, since
+                        * where_is_object_time will change the object which breaks transform */
+                       oblist = MEM_callocN(totgroup*sizeof(Object *), "dupgroup object list");
+                       obcopylist = MEM_callocN(totgroup*sizeof(Object), "dupgroup copy list");
+
+                       go = part->dup_group->gobject.first;
+                       for(a=0; a<totgroup; a++, go=go->next) {
+                               oblist[a] = go->ob;
+                               obcopylist[a] = *go->ob;
+                       }
                }
-               else
+               else {
                        ob = part->dup_ob;
+                       obcopy = *ob;
+               }
 
                if(totchild==0 || part->draw & PART_DRAW_PARENT)
-                       a=0;
+                       a = 0;
                else
-                       a=totpart;
+                       a = totpart;
 
                for(pa=psys->particles,counter=0; a<totpart+totchild; a++,pa++,counter++) {
                        if(a<totpart) {
+                               /* handle parent particle */
                                if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP))
                                        continue;
 
-                               pa_num=pa->num;
-
-                               pa_time=pa->time;
-
-                               size=pa->size;
+                               pa_num = pa->num;
+                               pa_time = pa->time;
+                               size = pa->size;
                        }
                        else {
-                               /* TODO: figure these two out */
-                               cpa= &psys->child[a - totpart];
+                               /* handle child particle */
+                               cpa = &psys->child[a - totpart];
+
                                pa_num = a;
                                pa_time = psys->particles[cpa->parent].time;
-
-                               size=psys_get_child_size(psys, cpa, ctime, 0);
+                               size = psys_get_child_size(psys, cpa, ctime, 0);
                        }
 
                        if(part->draw_as==PART_DRAW_GR) {
+                               /* for groups, pick the object based on settings */
                                if(part->draw&PART_DRAW_RAND_GR)
                                        b= BLI_rand() % totgroup;
                                else if(part->from==PART_FROM_PARTICLE)
@@ -829,13 +837,17 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                        b= a % totgroup;
 
                                ob = oblist[b];
-                               obmat= oblist[b]->obmat;
+                               obmat = oblist[b]->obmat;
+                               oldobmat = obcopylist[b].obmat;
                        }
-                       else
+                       else {
                                obmat= ob->obmat;
+                               oldobmat= obcopy.obmat;
+                       }
 
                        for(k=0; k<=step_nbr; k++, counter++) {
                                if(hair) {
+                                       /* hair we handle separate and compute transform based on hair keys */
                                        if(a < totpart) {
                                                cache = psys->pathcache[a];
                                                psys_get_dupli_path_transform(par, psys, psmd, pa, 0, cache, pamat, &scale);
@@ -848,6 +860,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                        VECCOPY(pamat[3], cache->co);
                                }
                                else if(step_nbr) {
+                                       /* other keys */
                                        state.time = (float)k / (float)step_nbr;
                                        psys_get_particle_on_path(par, psys, a, &state, 0);
 
@@ -856,6 +869,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                        pamat[3][3]= 1.0f;
                                }
                                else {
+                                       /* first key */
                                        state.time = -1.0;
                                        if(psys_get_particle_state(par, psys, a, &state, 0) == 0)
                                                continue;
@@ -876,6 +890,7 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                                        Mat4CpyMat4(mat, tmat);
 
                                                dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+                                               Mat4CpyMat4(dob->omat, oldobmat);
                                                if(G.rendering)
                                                        psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
                                        }
@@ -901,14 +916,27 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                                Mat4CpyMat4(mat, tmat);
 
                                        dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS, animated);
+                                       Mat4CpyMat4(dob->omat, oldobmat);
                                        if(G.rendering)
                                                psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
                                }
                        }
                }
+
+               /* restore objects since they were changed in where_is_object_time */
+               if(part->draw_as==PART_DRAW_GR) {
+                       for(a=0; a<totgroup; a++)
+                               *(oblist[a])= obcopylist[a];
+               }
+               else
+                       *ob= obcopy;
        }
+
+       /* clean up */
        if(oblist)
                MEM_freeN(oblist);
+       if(obcopylist)
+               MEM_freeN(obcopylist);
 
        if(psys->lattice) {
                end_latt_deform();
index f3637b4dda2e32d64379873f8a64f6ff962933f1..9ba47874d3cfbc86491cb6d6cebc9c45bd7ed068 100644 (file)
@@ -183,42 +183,43 @@ Collision modifier code end
  * copied from SOLVE_CUBIC.C --> GSL
  */
 
-/* DG: debug hint! don't forget that all functions were "fabs", "sinf", etc before */
-#define mySWAP(a,b) { float tmp = b ; b = a ; a = tmp ; }
+#define mySWAP(a,b) do { double tmp = b ; b = a ; a = tmp ; } while(0)
 
-int gsl_poly_solve_cubic ( float a, float b, float c, float *x0, float *x1, float *x2 )
+int 
+               gsl_poly_solve_cubic (double a, double b, double c, 
+                                                         double *x0, double *x1, double *x2)
 {
-       float q = ( a * a - 3 * b );
-       float r = ( 2 * a * a * a - 9 * a * b + 27 * c );
+       double q = (a * a - 3 * b);
+       double r = (2 * a * a * a - 9 * a * b + 27 * c);
 
-       float Q = q / 9;
-       float R = r / 54;
+       double Q = q / 9;
+       double R = r / 54;
 
-       float Q3 = Q * Q * Q;
-       float R2 = R * R;
+       double Q3 = Q * Q * Q;
+       double R2 = R * R;
 
-       float CR2 = 729 * r * r;
-       float CQ3 = 2916 * q * q * q;
+       double CR2 = 729 * r * r;
+       double CQ3 = 2916 * q * q * q;
 
-       if ( R == 0 && Q == 0 )
+       if (R == 0 && Q == 0)
        {
                *x0 = - a / 3 ;
                *x1 = - a / 3 ;
                *x2 = - a / 3 ;
                return 3 ;
        }
-       else if ( CR2 == CQ3 )
+       else if (CR2 == CQ3) 
        {
-               /* this test is actually R2 == Q3, written in a form suitable
+      /* this test is actually R2 == Q3, written in a form suitable
                for exact computation with integers */
 
-               /* Due to finite precision some float roots may be missed, and
+      /* Due to finite precision some double roots may be missed, and
                considered to be a pair of complex roots z = x +/- epsilon i
                close to the real axis. */
 
-               float sqrtQ = sqrt ( Q );
+               double sqrtQ = sqrt (Q);
 
-               if ( R > 0 )
+               if (R > 0)
                {
                        *x0 = -2 * sqrtQ  - a / 3;
                        *x1 = sqrtQ - a / 3;
@@ -232,72 +233,88 @@ int gsl_poly_solve_cubic ( float a, float b, float c, float *x0, float *x1, floa
                }
                return 3 ;
        }
-       else if ( CR2 < CQ3 ) /* equivalent to R2 < Q3 */
+       else if (CR2 < CQ3) /* equivalent to R2 < Q3 */
        {
-               float sqrtQ = sqrt ( Q );
-               float sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
-               float theta = acos ( R / sqrtQ3 );
-               float norm = -2 * sqrtQ;
-               *x0 = norm * cos ( theta / 3 ) - a / 3;
-               *x1 = norm * cos ( ( theta + 2.0 * M_PI ) / 3 ) - a / 3;
-               *x2 = norm * cos ( ( theta - 2.0 * M_PI ) / 3 ) - a / 3;
-
+               double sqrtQ = sqrt (Q);
+               double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ;
+               double theta = acos (R / sqrtQ3);
+               double norm = -2 * sqrtQ;
+               *x0 = norm * cos (theta / 3) - a / 3;
+               *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3;
+               *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3;
+      
                /* Sort *x0, *x1, *x2 into increasing order */
 
-               if ( *x0 > *x1 )
-                       mySWAP ( *x0, *x1 ) ;
-
-               if ( *x1 > *x2 )
+               if (*x0 > *x1)
+                       mySWAP(*x0, *x1) ;
+      
+               if (*x1 > *x2)
                {
-                       mySWAP ( *x1, *x2 ) ;
-
-                       if ( *x0 > *x1 )
-                               mySWAP ( *x0, *x1 ) ;
+                       mySWAP(*x1, *x2) ;
+          
+                       if (*x0 > *x1)
+                               mySWAP(*x0, *x1) ;
                }
-
+      
                return 3;
        }
        else
        {
-               float sgnR = ( R >= 0 ? 1 : -1 );
-               float A = -sgnR * pow ( ABS ( R ) + sqrt ( R2 - Q3 ), 1.0/3.0 );
-               float B = Q / A ;
+               double sgnR = (R >= 0 ? 1 : -1);
+               double A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0);
+               double B = Q / A ;
                *x0 = A + B - a / 3;
                return 1;
        }
 }
 
 
+
 /**
  * gsl_poly_solve_quadratic
  *
  * copied from GSL
  */
-int gsl_poly_solve_quadratic ( float a, float b, float c,  float *x0, float *x1 )
+int 
+               gsl_poly_solve_quadratic (double a, double b, double c, 
+                                                                 double *x0, double *x1)
 {
-       float disc = b * b - 4 * a * c;
+       double disc = b * b - 4 * a * c;
+
+       if (a == 0) /* Handle linear case */
+       {
+               if (b == 0)
+               {
+                       return 0;
+               }
+               else
+               {
+                       *x0 = -c / b;
+                       return 1;
+               };
+       }
 
-       if ( disc > 0 )
+       if (disc > 0)
        {
-               if ( b == 0 )
+               if (b == 0)
                {
-                       float r = ABS ( 0.5 * sqrt ( disc ) / a );
+                       double r = fabs (0.5 * sqrt (disc) / a);
                        *x0 = -r;
                        *x1 =  r;
                }
                else
                {
-                       float sgnb = ( b > 0 ? 1 : -1 );
-                       float temp = -0.5 * ( b + sgnb * sqrt ( disc ) );
-                       float r1 = temp / a ;
-                       float r2 = c / temp ;
+                       double sgnb = (b > 0 ? 1 : -1);
+                       double temp = -0.5 * (b + sgnb * sqrt (disc));
+                       double r1 = temp / a ;
+                       double r2 = c / temp ;
 
-                       if ( r1 < r2 )
+                       if (r1 < r2) 
                        {
                                *x0 = r1 ;
                                *x1 = r2 ;
-                       }
-                       else
+                       } 
+                       else 
                        {
                                *x0 = r2 ;
                                *x1 = r1 ;
@@ -305,7 +322,7 @@ int gsl_poly_solve_quadratic ( float a, float b, float c,  float *x0, float *x1
                }
                return 2;
        }
-       else if ( disc == 0 )
+       else if (disc == 0) 
        {
                *x0 = -0.5 * b / a ;
                *x1 = -0.5 * b / a ;
@@ -319,79 +336,88 @@ int gsl_poly_solve_quadratic ( float a, float b, float c,  float *x0, float *x1
 
 
 
+
 /*
  * See Bridson et al. "Robust Treatment of Collision, Contact and Friction for Cloth Animation"
  *     page 4, left column
  */
-
-int cloth_get_collision_time ( float a[3], float b[3], float c[3], float d[3], float e[3], float f[3], float solution[3] )
+int cloth_get_collision_time ( double a[3], double b[3], double c[3], double d[3], double e[3], double f[3], double solution[3] )
 {
        int num_sols = 0;
 
-       float g = -a[2] * c[1] * e[0] + a[1] * c[2] * e[0] +
-                 a[2] * c[0] * e[1] - a[0] * c[2] * e[1] -
-                 a[1] * c[0] * e[2] + a[0] * c[1] * e[2];
-
-       float h = -b[2] * c[1] * e[0] + b[1] * c[2] * e[0] - a[2] * d[1] * e[0] +
-                 a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] +
-                 a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] +
-                 b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] -
-                 a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] -
-                 a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2];
-
-       float i = -b[2] * d[1] * e[0] + b[1] * d[2] * e[0] +
-                 b[2] * d[0] * e[1] - b[0] * d[2] * e[1] -
-                 b[1] * d[0] * e[2] + b[0] * d[1] * e[2] -
-                 b[2] * c[1] * f[0] + b[1] * c[2] * f[0] -
-                 a[2] * d[1] * f[0] + a[1] * d[2] * f[0] +
-                 b[2] * c[0] * f[1] - b[0] * c[2] * f[1] +
-                 a[2] * d[0] * f[1] - a[0] * d[2] * f[1] -
-                 b[1] * c[0] * f[2] + b[0] * c[1] * f[2] -
-                 a[1] * d[0] * f[2] + a[0] * d[1] * f[2];
-
-       float j = -b[2] * d[1] * f[0] + b[1] * d[2] * f[0] +
-                 b[2] * d[0] * f[1] - b[0] * d[2] * f[1] -
-                 b[1] * d[0] * f[2] + b[0] * d[1] * f[2];
+       // x^0 - checked 
+       double g =      a[0] * c[1] * e[2] - a[0] * c[2] * e[1] +
+                               a[1] * c[2] * e[0] - a[1] * c[0] * e[2] + 
+                               a[2] * c[0] * e[1] - a[2] * c[1] * e[0];
+       
+       // x^1
+       double h = -b[2] * c[1] * e[0] + b[1] * c[2] * e[0] - a[2] * d[1] * e[0] +
+                       a[1] * d[2] * e[0] + b[2] * c[0] * e[1] - b[0] * c[2] * e[1] +
+                       a[2] * d[0] * e[1] - a[0] * d[2] * e[1] - b[1] * c[0] * e[2] +
+                       b[0] * c[1] * e[2] - a[1] * d[0] * e[2] + a[0] * d[1] * e[2] -
+                       a[2] * c[1] * f[0] + a[1] * c[2] * f[0] + a[2] * c[0] * f[1] -
+                       a[0] * c[2] * f[1] - a[1] * c[0] * f[2] + a[0] * c[1] * f[2];
+
+       // x^2
+       double i = -b[2] * d[1] * e[0] + b[1] * d[2] * e[0] +
+                       b[2] * d[0] * e[1] - b[0] * d[2] * e[1] -
+                       b[1] * d[0] * e[2] + b[0] * d[1] * e[2] -
+                       b[2] * c[1] * f[0] + b[1] * c[2] * f[0] -
+                       a[2] * d[1] * f[0] + a[1] * d[2] * f[0] +
+                       b[2] * c[0] * f[1] - b[0] * c[2] * f[1] + 
+                       a[2] * d[0] * f[1] - a[0] * d[2] * f[1] -
+                       b[1] * c[0] * f[2] + b[0] * c[1] * f[2] -
+                       a[1] * d[0] * f[2] + a[0] * d[1] * f[2];
+       
+       // x^3 - checked
+       double j = -b[2] * d[1] * f[0] + b[1] * d[2] * f[0] +
+                       b[2] * d[0] * f[1] - b[0] * d[2] * f[1] -
+                       b[1] * d[0] * f[2] + b[0] * d[1] * f[2];
+       
+       /*
+       printf("r1: %lf\n", a[0] * c[1] * e[2] - a[0] * c[2] * e[1]);
+       printf("r2: %lf\n", a[1] * c[2] * e[0] - a[1] * c[0] * e[2]);
+       printf("r3: %lf\n", a[2] * c[0] * e[1] - a[2] * c[1] * e[0]);
+       
+       printf("x1 x: %f, y: %f, z: %f\n", a[0], a[1], a[2]);
+       printf("x2 x: %f, y: %f, z: %f\n", c[0], c[1], c[2]);
+       printf("x3 x: %f, y: %f, z: %f\n", e[0], e[1], e[2]);
+       
+       printf("v1 x: %f, y: %f, z: %f\n", b[0], b[1], b[2]);
+       printf("v2 x: %f, y: %f, z: %f\n", d[0], d[1], d[2]);
+       printf("v3 x: %f, y: %f, z: %f\n", f[0], f[1], f[2]);
+       
+       printf("t^3: %lf, t^2: %lf, t^1: %lf, t^0: %lf\n", j, i, h, g);
+       */
 
        // Solve cubic equation to determine times t1, t2, t3, when the collision will occur.
-       if ( ABS ( j ) > ALMOST_ZERO )
+       if ( ABS ( j ) > DBL_EPSILON )
        {
                i /= j;
                h /= j;
                g /= j;
-
                num_sols = gsl_poly_solve_cubic ( i, h, g, &solution[0], &solution[1], &solution[2] );
        }
-       else if ( ABS ( i ) > ALMOST_ZERO )
+       else
        {
                num_sols = gsl_poly_solve_quadratic ( i, h, g, &solution[0], &solution[1] );
                solution[2] = -1.0;
        }
-       else if ( ABS ( h ) > ALMOST_ZERO )
-       {
-               solution[0] = -g / h;
-               solution[1] = solution[2] = -1.0;
-               num_sols = 1;
-       }
-       else if ( ABS ( g ) > ALMOST_ZERO )
-       {
-               solution[0] = 0;
-               solution[1] = solution[2] = -1.0;
-               num_sols = 1;
-       }
+
+       // printf("num_sols: %d, sol1: %lf, sol2: %lf, sol3: %lf\n", num_sols, solution[0],  solution[1],  solution[2]);
 
        // Discard negative solutions
-       if ( ( num_sols >= 1 ) && ( solution[0] < 0 ) )
+       if ( ( num_sols >= 1 ) && ( solution[0] < DBL_EPSILON ) )
        {
                --num_sols;
                solution[0] = solution[num_sols];
        }
-       if ( ( num_sols >= 2 ) && ( solution[1] < 0 ) )
+       if ( ( num_sols >= 2 ) && ( solution[1] < DBL_EPSILON ) )
        {
                --num_sols;
                solution[1] = solution[num_sols];
        }
-       if ( ( num_sols == 3 ) && ( solution[2] < 0 ) )
+       if ( ( num_sols == 3 ) && ( solution[2] < DBL_EPSILON ) )
        {
                --num_sols;
        }
@@ -736,21 +762,72 @@ int cloth_are_edges_adjacent ( ClothModifierData *clmd, CollisionModifierData *c
        return 0;
 }
 
-void cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
+int cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair )
 {
        EdgeCollPair edgecollpair;
        Cloth *cloth1=NULL;
        ClothVertex *verts1=NULL;
        unsigned int i = 0, j = 0, k = 0;
        int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+       double x1[3], v1[3], x2[3], v2[3], x3[3], v3[3];
+       double solution[3];
        MVert *verts2 = collmd->current_x; // old x
        MVert *velocity2 = collmd->current_v; // velocity
-       float mintime = 0;
+       float mintime = FLT_MAX;
+       float distance;
+       float triA[3][3], triB[3][3];
+       int result = 0;
 
        cloth1 = clmd->clothObject;
        verts1 = cloth1->verts;
+       
+       /*
+       double p[4][3] = {{0,0,0},{0,2,0},{1,1,-1},{1,1,1}};
+       double v[4][3] = {{0,0,0},{1,0,0},{-2,0,0},{-2,0,0}};
+       
+       double pp[2][3] = {{-1,-1,-1}, {2,2,2}};
+       
+       
+       VECSUB ( x1, p[1], p[0] );
+       VECSUB ( v1, v[1], v[0] );
+                       
+       VECSUB ( x2, p[2], p[0] );
+       VECSUB ( v2, v[2], v[0] );
+                       
+       VECSUB ( x3, p[3], p[0] );
+       VECSUB ( v3, v[3], v[0] );
 
+       printf("x1 x: %f, y: %f, z: %f\n", x1[0], x1[1], x1[2]);
+       printf("x2 x: %f, y: %f, z: %f\n", x2[0], x2[1], x2[2]);
+       printf("x3 x: %f, y: %f, z: %f\n", x3[0], x3[1], x3[2]);
+       
+       printf("v1 x: %f, y: %f, z: %f\n", v1[0], v1[1], v1[2]);
+       printf("v2 x: %f, y: %f, z: %f\n", v2[0], v2[1], v2[2]);
+       printf("v3 x: %f, y: %f, z: %f\n", v3[0], v3[1], v3[2]);
+
+       numsolutions = cloth_get_collision_time ( x1, v1, x2, v2, x3, v3, solution );
+       
+       for ( k = 0; k < numsolutions; k++ )
+               printf("mintime: %f\n", solution[k]);
+       
+       mintime = solution[0];
+       
+       // move triangles to collision point in time
+       VECADDS(triA[0], pp[0], v[0], solution[0]);
+       VECADDS(triA[1], p[0], v[0], solution[0]);
+       VECADDS(triA[2], p[1], v[1], solution[0]);
+               
+       VECADDS(triB[0], pp[1], v[0], solution[0]);
+       VECADDS(triB[1], p[2], v[2], solution[0]);
+       VECADDS(triB[2], p[3], v[3], solution[0]);
+               
+               // check distance there
+       distance = plNearestPoints (triA[0], triA[1], triA[2], triB[0], triB[1], triB[2], collpair->pa,collpair->pb,collpair->vector );
+       
+       printf("mintime: %f, dist: %f\n", mintime, distance);
+       
+       exit(0);
+       */
        for(i = 0; i < 9; i++)
        {
                // 9 edge - edge possibilities
@@ -831,18 +908,28 @@ void cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDa
                if ( !cloth_are_edges_adjacent ( clmd, collmd, &edgecollpair ) )
                {
                        // always put coll points in p21/p22
-                       VECSUB ( a, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold );
-                       VECSUB ( b, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv );
-                       VECSUB ( c, verts2[edgecollpair.p21].co, verts1[edgecollpair.p11].txold );
-                       VECSUB ( d, velocity2[edgecollpair.p21].co, verts1[edgecollpair.p11].tv );
-                       VECSUB ( e, verts2[edgecollpair.p22].co, verts1[edgecollpair.p11].txold );
-                       VECSUB ( f, velocity2[edgecollpair.p22].co, verts1[edgecollpair.p11].v );
-       
-                       numsolutions = cloth_get_collision_time ( a, b, c, d, e, f, solution );
+                       VECSUB ( x1, verts1[edgecollpair.p12].txold, verts1[edgecollpair.p11].txold );
+                       VECSUB ( v1, verts1[edgecollpair.p12].tv, verts1[edgecollpair.p11].tv );
+                       
+                       VECSUB ( x2, verts2[edgecollpair.p21].co, verts1[edgecollpair.p11].txold );
+                       VECSUB ( v2, velocity2[edgecollpair.p21].co, verts1[edgecollpair.p11].tv );
+                       
+                       VECSUB ( x3, verts2[edgecollpair.p22].co, verts1[edgecollpair.p11].txold );
+                       VECSUB ( v3, velocity2[edgecollpair.p22].co, verts1[edgecollpair.p11].tv );
+                       /*
+                       printf("A x: %f, y: %f, z: %f\n", a[0], a[1], a[2]);
+                       printf("B x: %f, y: %f, z: %f\n", b[0], b[1], b[2]);
+                       printf("C x: %f, y: %f, z: %f\n", c[0], c[1], c[2]);
+                       printf("D x: %f, y: %f, z: %f\n", d[0], d[1], d[2]);
+                       printf("E x: %f, y: %f, z: %f\n", e[0], e[1], e[2]);
+                       printf("F x: %f, y: %f, z: %f\n", f[0], f[1], f[2]);
+                       exit(0);
+                       */
+                       numsolutions = cloth_get_collision_time ( x1, v1, x2, v2, x3, v3, solution );
        
                        for ( k = 0; k < numsolutions; k++ )
                        {
-                               if ( ( solution[k] >= 0.0 ) && ( solution[k] <= 1.0 ) )
+                               if ( ( solution[k] >= DBL_EPSILON ) && ( solution[k] <= 1.0 ) )
                                {
                                        //float out_collisionTime = solution[k];
        
@@ -850,14 +937,35 @@ void cloth_collision_moving_edges ( ClothModifierData *clmd, CollisionModifierDa
        
                                        // TODO: put into (edge) collision list
                                        
-                                       mintime = MIN2(mintime, solution[k]);
-       
-                                       printf("Moving edge found!, mintime: %f\n", mintime);
+                                       mintime = MIN2(mintime, (float)solution[k]);
+                                       
+//                                     printf("mt: %f, %lf, %f\n", mintime, solution[k], (float)solution[k]);
+                                       
+                                       result = 1;
                                        break;
                                }
                        }
                }
        }
+       
+       if(result)
+       {
+               // move triangles to collision point in time
+               VECADDS(triA[0], verts1[collpair->ap1].txold, verts1[collpair->ap1].tv, mintime);
+               VECADDS(triA[1], verts1[collpair->ap2].txold, verts1[collpair->ap2].tv, mintime);
+               VECADDS(triA[2], verts1[collpair->ap3].txold, verts1[collpair->ap3].tv, mintime);
+               
+               VECADDS(triB[0], collmd->current_x[collpair->bp1].co, collmd->current_v[collpair->bp1].co, mintime);
+               VECADDS(triB[1], collmd->current_x[collpair->bp2].co, collmd->current_v[collpair->bp2].co, mintime);
+               VECADDS(triB[2], collmd->current_x[collpair->bp3].co, collmd->current_v[collpair->bp3].co, mintime);
+               
+               // check distance there
+               distance = plNearestPoints (triA[0], triA[1], triA[2], triB[0], triB[1], triB[2], collpair->pa,collpair->pb,collpair->vector );
+               
+               printf("mintime: %f, dist: %f\n", mintime, distance);
+       }
+       
+       return result;
 }
 
 void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *coll_clmd, CollisionTree *tree1, CollisionTree *tree2 )
@@ -868,7 +976,8 @@ void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *c
        ClothVertex *verts1=NULL, *verts2=NULL;
        unsigned int i = 0, j = 0, k = 0;
        int numsolutions = 0;
-       float a[3], b[3], c[3], d[3], e[3], f[3], solution[3];
+       float a[3], b[3], c[3], d[3], e[3], f[3];
+       double solution[3];
 
        for ( i = 0; i < 2; i++ )
        {
@@ -932,7 +1041,7 @@ void cloth_collision_moving_tris ( ClothModifierData *clmd, ClothModifierData *c
 
                                for ( k = 0; k < numsolutions; k++ )
                                {
-                                       if ( ( solution[k] >= 0.0 ) && ( solution[k] <= 1.0 ) )
+                                       if ( ( solution[k] >= ALMOST_ZERO ) && ( solution[k] <= 1.0 ) )
                                        {
                                                //float out_collisionTime = solution[k];
 
@@ -982,6 +1091,8 @@ int cloth_collision_moving ( ClothModifierData *clmd, CollisionModifierData *col
                
                cloth_collision_moving_edges ( clmd, collmd, collpair);
        }
+       
+       return 1;
 }
 
 int cloth_bvh_objcollisions_do ( ClothModifierData * clmd, CollisionModifierData *collmd, float step, float dt )
index 1331c9a7d126808e4a995883a55236683d562e48..80f450000bbc7356b5a24419ba9f955b87485369 100644 (file)
@@ -346,6 +346,24 @@ static void dag_add_driver_relation(Ipo *ipo, DagForest *dag, DagNode *node, int
        }
 }
 
+static void dag_add_collision_field_relation(DagForest *dag, Object *ob, DagNode *node)
+{
+       Base *base;
+       DagNode *node2;
+
+       // would be nice to have a list of colliders here
+       // so for now walk all objects in scene check 'same layer rule'
+       for(base = G.scene->base.first; base; base= base->next) {
+               if((base->lay & ob->lay) && base->object->pd) {
+                       Object *ob1= base->object;
+                       if((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob))  {
+                               node2 = dag_get_node(dag, ob1);                                 
+                               dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Field Collision");
+                       }
+               }
+       }
+}
+
 static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int mask)
 {
        bConstraint *con;
@@ -523,22 +541,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Object *ob, int
        }
     
        /* softbody collision  */
-       if((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE)) {
-               Base *base;
-               if(modifiers_isSoftbodyEnabled(ob)){
-                       // would be nice to have a list of colliders here
-                       // so for now walk all objects in scene check 'same layer rule'
-                       for(base = G.scene->base.first; base; base= base->next) {
-                               if( (base->lay & ob->lay) && base->object->pd) {
-                                       Object *ob1= base->object;
-                                       if((ob1->pd->deflect) && (ob1 != ob))  {
-                                               node2 = dag_get_node(dag, ob1);                                 
-                                               dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Softbody Collision");
-                                       }
-                               }
-                       }
-               }
-       }
+       if((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE))
+               if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob))
+                       dag_add_collision_field_relation(dag, ob, node);
                
        if (ob->type==OB_MBALL) {
                Object *mom= find_basis_mball(ob);
@@ -1691,7 +1696,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
                for(itA = node->child; itA; itA= itA->next) {
                        all_layer |= itA->lay;
                        /* the relationship is visible */
-                       if(itA->lay & layer) {
+                       if((itA->lay & layer) || (itA->node->ob == G.obedit)) {
                                if(itA->node->type==ID_OB) {
                                        obc= itA->node->ob;
                                        oldflag= obc->recalc;
@@ -1722,7 +1727,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
                        }
                }
                /* even nicer, we can clear recalc flags...  */
-               if((all_layer & layer)==0) {
+               if((all_layer & layer)==0 && (ob != G.obedit)) {
                        /* but existing displaylists or derivedmesh should be freed */
                        if(ob->recalc & OB_RECALC_DATA)
                                object_free_display(ob);
@@ -1736,7 +1741,7 @@ static void flush_update_node(DagNode *node, unsigned int layer, int curtime)
        /* could merge this in with loop above...? (ton) */
        for(itA = node->child; itA; itA= itA->next) {
                /* the relationship is visible */
-               if(itA->lay & layer) {
+               if((itA->lay & layer) || (itA->node->ob == G.obedit)) {
                        if(itA->node->type==ID_OB) {
                                obc= itA->node->ob;
                                /* child moves */
index 0b9f7615bfa821c1d8d8bb391b54a510bd6e11a1..321d4f1d37e0b23d53c66446a4ff5e7f2dc49706 100644 (file)
@@ -1917,6 +1917,9 @@ void set_icu_vars(IpoCurve *icu)
                        icu->ymin= 0.0;
                        break;
                case PART_CLUMP:
+                       icu->ymin= -1.0;
+                       icu->ymax= 1.0;
+                       break;
                case PART_DRAG:
                case PART_DAMP:
                case PART_LENGTH:
@@ -1926,6 +1929,7 @@ void set_icu_vars(IpoCurve *icu)
                case PART_KINK_SHAPE:
                        icu->ymin= -0.999;
                        icu->ymax= 0.999;
+                       break;
                }
        }
        else if(icu->blocktype==ID_CO) {
index 16916381c95b74c364d2b7e4bc46be29264d706a..0cd7736f6c3f694b47ee711bc8104a6d9cf161a9 100644 (file)
@@ -1363,8 +1363,9 @@ void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
                                        out_v = mbproc->function(out.x, out.y, out.z);
 
                                        /* find "first points" on Implicit Surface of MetaElemnt ml */
-                                       //converge(&in, &out, in_v, out_v, mbproc->function, &mbproc->start, mb, 0);
-                                       workp = in;
+                                       workp.x = in.x;
+                                       workp.y = in.y;
+                                       workp.z = in.z;
                                        workp_v = in_v;
                                        max_len = sqrt((out.x-in.x)*(out.x-in.x) + (out.y-in.y)*(out.y-in.y) + (out.z-in.z)*(out.z-in.z));
 
index 472fd9511684e6fef1ce25dcde53bb1d1e260d9c..a29c10a95ac4894b64f38df5c47c541cc56b9cd6 100644 (file)
@@ -5958,6 +5958,8 @@ static void explodeModifier_copyData(ModifierData *md, ModifierData *target)
 
        temd->facepa = 0;
        temd->flag = emd->flag;
+       temd->protect = emd->protect;
+       temd->vgroup = emd->vgroup;
 }
 static int explodeModifier_dependsOnTime(ModifierData *md) 
 {
@@ -6078,20 +6080,29 @@ static void explodeModifier_createFacepa(ExplodeModifierData *emd,
        if(vertpa) MEM_freeN(vertpa);
        BLI_kdtree_free(tree);
 }
+
+static int edgesplit_get(EdgeHash *edgehash, int v1, int v2)
+{
+       return GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, v1, v2));
+}
+
 static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, DerivedMesh *dm){
        DerivedMesh *splitdm;
        MFace *mf=0,*df1=0,*df2=0,*df3=0;
        MFace *mface=CDDM_get_faces(dm);
        MVert *dupve, *mv;
+       EdgeHash *edgehash;
+       EdgeHashIterator *ehi;
        int totvert=dm->getNumVerts(dm);
        int totface=dm->getNumFaces(dm);
 
-       int *edgesplit = MEM_callocN(sizeof(int)*totvert*totvert,"explode_edgesplit");
-       int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_edgesplit");
+       int *facesplit = MEM_callocN(sizeof(int)*totface,"explode_facesplit");
        int *vertpa = MEM_callocN(sizeof(int)*totvert,"explode_vertpa2");
        int *facepa = emd->facepa;
        int *fs, totesplit=0,totfsplit=0,totin=0,curdupvert=0,curdupface=0,curdupin=0;
-       int i,j,v1,v2,v3,v4;
+       int i,j,v1,v2,v3,v4,esplit;
+
+       edgehash= BLI_edgehash_new();
 
        /* recreate vertpa from facepa calculation */
        for (i=0,mf=mface; i<totface; i++,mf++) {
@@ -6111,22 +6122,22 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                        v4=vertpa[mf->v4];
 
                        if(v1!=v2){
-                               edgesplit[mf->v1*totvert+mf->v2]=edgesplit[mf->v2*totvert+mf->v1]=1;
+                               BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
                                (*fs)++;
                        }
 
                        if(v2!=v3){
-                               edgesplit[mf->v2*totvert+mf->v3]=edgesplit[mf->v3*totvert+mf->v2]=1;
+                               BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
                                (*fs)++;
                        }
 
                        if(v3!=v4){
-                               edgesplit[mf->v3*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v3]=1;
+                               BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
                                (*fs)++;
                        }
 
                        if(v1!=v4){
-                               edgesplit[mf->v1*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v1]=1;
+                               BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
                                (*fs)++;
                        }
 
@@ -6135,28 +6146,29 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                        *fs=1;
                                else if(v1!=v2){
                                        if(v1!=v4)
-                                               edgesplit[mf->v2*totvert+mf->v3]=edgesplit[mf->v3*totvert+mf->v2]=1;
+                                               BLI_edgehash_insert(edgehash, mf->v2, mf->v3, NULL);
                                        else
-                                               edgesplit[mf->v3*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v3]=1;
+                                               BLI_edgehash_insert(edgehash, mf->v3, mf->v4, NULL);
                                }
                                else{ 
                                        if(v1!=v4)
-                                               edgesplit[mf->v1*totvert+mf->v2]=edgesplit[mf->v2*totvert+mf->v1]=1;
+                                               BLI_edgehash_insert(edgehash, mf->v1, mf->v2, NULL);
                                        else
-                                               edgesplit[mf->v1*totvert+mf->v4]=edgesplit[mf->v4*totvert+mf->v1]=1;
+                                               BLI_edgehash_insert(edgehash, mf->v1, mf->v4, NULL);
                                }
                        }
                }
        }
 
        /* count splits & reindex */
+       ehi= BLI_edgehashIterator_new(edgehash);
        totesplit=totvert;
-       for(j=0; j<totvert; j++){
-               for(i=j+1; i<totvert; i++){
-                       if(edgesplit[j*totvert+i])
-                               edgesplit[j*totvert+i]=edgesplit[i*totvert+j]=totesplit++;
-               }
+       for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+               BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(totesplit));
+               totesplit++;
        }
+       BLI_edgehashIterator_free(ehi);
+
        /* count new faces due to splitting */
        for(i=0,fs=facesplit; i<totface; i++,fs++){
                if(*fs==1)
@@ -6204,23 +6216,23 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
 
        /* create new verts */
        curdupvert=totvert;
-       for(j=0; j<totvert; j++){
-               for(i=j+1; i<totvert; i++){
-                       if(edgesplit[j*totvert+i]){
-                               mv=CDDM_get_vert(splitdm,j);
-                               dupve=CDDM_get_vert(splitdm,edgesplit[j*totvert+i]);
+       ehi= BLI_edgehashIterator_new(edgehash);
+       for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) {
+               BLI_edgehashIterator_getKey(ehi, &i, &j);
+               esplit= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
+               mv=CDDM_get_vert(splitdm,j);
+               dupve=CDDM_get_vert(splitdm,esplit);
 
-                               DM_copy_vert_data(splitdm,splitdm,j,edgesplit[j*totvert+i],1);
+               DM_copy_vert_data(splitdm,splitdm,j,esplit,1);
 
-                               *dupve=*mv;
+               *dupve=*mv;
 
-                               mv=CDDM_get_vert(splitdm,i);
+               mv=CDDM_get_vert(splitdm,i);
 
-                               VECADD(dupve->co,dupve->co,mv->co);
-                               VecMulf(dupve->co,0.5);
-                       }
-               }
+               VECADD(dupve->co,dupve->co,mv->co);
+               VecMulf(dupve->co,0.5);
        }
+       BLI_edgehashIterator_free(ehi);
 
        /* create new faces */
        curdupface=totface;
@@ -6241,14 +6253,14 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                curdupface++;
                                
                                if(v1==v2){
-                                       df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-                                       df1->v2=edgesplit[mf->v2*totvert+mf->v3];
+                                       df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+                                       df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
                                        mf->v3=df1->v2;
                                        mf->v4=df1->v1;
                                }
                                else{
-                                       df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-                                       df1->v4=edgesplit[mf->v3*totvert+mf->v4];
+                                       df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                       df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
                                        mf->v2=df1->v1;
                                        mf->v3=df1->v4;
                                }
@@ -6271,8 +6283,8 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
 
                                if(v1!=v2){
                                        if(v1!=v4){
-                                               df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-                                               df1->v2=edgesplit[mf->v1*totvert+mf->v2];
+                                               df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+                                               df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
                                                df2->v1=df1->v3=mf->v2;
                                                df2->v3=df1->v4=mf->v4;
                                                df2->v2=mf->v3;
@@ -6285,8 +6297,8 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                                facepa[i]=v1;
                                        }
                                        else{
-                                               df1->v2=edgesplit[mf->v1*totvert+mf->v2];
-                                               df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+                                               df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                               df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
                                                df1->v4=mf->v3;
                                                df2->v2=mf->v3;
                                                df2->v3=mf->v4;
@@ -6302,8 +6314,8 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                }
                                else{
                                        if(v1!=v4){
-                                               df1->v3=edgesplit[mf->v3*totvert+mf->v4];
-                                               df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+                                               df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
+                                               df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
                                                df1->v2=mf->v3;
 
                                                mf->v1=df1->v4;
@@ -6315,8 +6327,8 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                                facepa[i]=v4;
                                        }
                                        else{
-                                               df1->v3=edgesplit[mf->v2*totvert+mf->v3];
-                                               df1->v4=edgesplit[mf->v3*totvert+mf->v4];
+                                               df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
+                                               df1->v4=edgesplit_get(edgehash, mf->v3, mf->v4);
                                                df1->v1=mf->v4;
                                                df1->v2=mf->v2;
                                                df2->v3=mf->v4;
@@ -6352,9 +6364,9 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                curdupface++;
 
                                if(v1==v2){
-                                       df2->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-                                       df3->v1=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
-                                       df3->v3=df2->v2=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+                                       df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+                                       df3->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
+                                       df3->v3=df2->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
                                        df3->v2=mf->v3;
                                        df2->v3=mf->v4;
                                        df1->v4=df2->v4=df3->v4=0;
@@ -6367,9 +6379,9 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                        facepa[curdupface-2]=v4;
                                }
                                else if(v2==v3){
-                                       df3->v1=df2->v3=df1->v1=edgesplit[mf->v1*totvert+mf->v4];
-                                       df2->v2=df1->v2=edgesplit[mf->v1*totvert+mf->v2];
-                                       df3->v2=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+                                       df3->v1=df2->v3=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+                                       df2->v2=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                       df3->v2=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
                                        df3->v3=mf->v4;
                                        df2->v1=mf->v1;
@@ -6383,9 +6395,9 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                        facepa[curdupface-2]=v1;
                                }
                                else if(v3==v4){
-                                       df3->v2=df2->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-                                       df2->v3=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
-                                       df3->v3=df1->v3=edgesplit[mf->v1*totvert+mf->v4];
+                                       df3->v2=df2->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                       df2->v3=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
+                                       df3->v3=df1->v3=edgesplit_get(edgehash, mf->v1, mf->v4);
 
                                        df3->v1=mf->v1;
                                        df2->v2=mf->v2;
@@ -6399,9 +6411,9 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                        facepa[curdupface-2]=v2;
                                }
                                else{
-                                       df3->v1=df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-                                       df3->v3=df2->v1=df1->v2=edgesplit[mf->v2*totvert+mf->v3];
-                                       df2->v3=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
+                                       df3->v1=df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                       df3->v3=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
+                                       df2->v3=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
                                        df3->v2=mf->v2;
                                        df2->v2=mf->v3;
@@ -6452,11 +6464,11 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                        *df3=*mf;
                                        curdupface++;
 
-                                       df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-                                       df3->v2=df1->v3=edgesplit[mf->v2*totvert+mf->v3];
+                                       df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                       df3->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
 
-                                       df2->v1=edgesplit[mf->v1*totvert+mf->v4];
-                                       df3->v4=df2->v3=edgesplit[mf->v3*totvert+mf->v4];
+                                       df2->v1=edgesplit_get(edgehash, mf->v1, mf->v4);
+                                       df3->v4=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
                                        df3->v1=df2->v2=df1->v4=curdupin;
 
@@ -6493,11 +6505,11 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                        curdupface++;
 
                                        if(v2==v3){
-                                               df1->v1=edgesplit[mf->v1*totvert+mf->v2];
-                                               df3->v1=df1->v2=df1->v3=edgesplit[mf->v2*totvert+mf->v3];
-                                               df2->v1=df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+                                               df1->v1=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                               df3->v1=df1->v2=df1->v3=edgesplit_get(edgehash, mf->v2, mf->v3);
+                                               df2->v1=df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
 
-                                               df3->v3=df2->v3=edgesplit[mf->v3*totvert+mf->v4];
+                                               df3->v3=df2->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
 
                                                df3->v2=mf->v3;
                                                df3->v4=0;
@@ -6511,11 +6523,11 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                                                facepa[curdupface-1]=v3;
                                        }
                                        else{
-                                               df3->v1=df2->v1=df1->v2=edgesplit[mf->v1*totvert+mf->v2];
-                                               df2->v4=df1->v3=edgesplit[mf->v3*totvert+mf->v4];
-                                               df1->v4=edgesplit[mf->v1*totvert+mf->v4];
+                                               df3->v1=df2->v1=df1->v2=edgesplit_get(edgehash, mf->v1, mf->v2);
+                                               df2->v4=df1->v3=edgesplit_get(edgehash, mf->v3, mf->v4);
+                                               df1->v4=edgesplit_get(edgehash, mf->v1, mf->v4);
 
-                                               df3->v3=df2->v2=edgesplit[mf->v2*totvert+mf->v3];
+                                               df3->v3=df2->v2=edgesplit_get(edgehash, mf->v2, mf->v3);
 
                                                df3->v4=0;
 
@@ -6539,7 +6551,7 @@ static DerivedMesh * explodeModifier_splitEdges(ExplodeModifierData *emd, Derive
                }
        }
 
-       MEM_freeN(edgesplit);
+       BLI_edgehash_free(edgehash, NULL);
        MEM_freeN(facesplit);
        MEM_freeN(vertpa);
 
index 5594a1dfaf7f2d6671dbf84696bfce04f8c1d190..a2a7894e3ce024af8f219327ce5abcb4bcd641af 100644 (file)
@@ -1054,7 +1054,11 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
        psysn->childcache= NULL;
        psysn->edit= NULL;
        psysn->effectors.first= psysn->effectors.last= 0;
-
+       
+       psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
+       psysn->reactevents.first = psysn->reactevents.last = NULL;
+       psysn->renderdata = NULL;
+       
        psysn->pointcache= BKE_ptcache_copy(psys->pointcache);
 
        id_us_plus((ID *)psysn->part);
index 2aa0d0ad0b89df7fd038ff823727541069fd8cda..fec3da752ff6bdb576b88be4c04649bcf29236dc 100644 (file)
@@ -152,6 +152,49 @@ char *psys_menu_string(Object *ob, int for_sb)
 
        return str;
 }
+
+/* we allocate path cache memory in chunks instead of a big continguous
+ * chunk, windows' memory allocater fails to find big blocks of memory often */
+
+#define PATH_CACHE_BUF_SIZE 1024
+
+static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, int steps)
+{
+       LinkData *buf;
+       ParticleCacheKey **cache;
+       int i, totkey, totbufkey;
+
+       tot= MAX2(tot, 1);
+       totkey = 0;
+       cache = MEM_callocN(tot*sizeof(void*), "PathCacheArray");
+
+       while(totkey < tot) {
+               totbufkey= MIN2(tot-totkey, PATH_CACHE_BUF_SIZE);
+               buf= MEM_callocN(sizeof(LinkData), "PathCacheLinkData");
+               buf->data= MEM_callocN(sizeof(ParticleCacheKey)*totbufkey*steps, "ParticleCacheKey");
+
+               for(i=0; i<totbufkey; i++)
+                       cache[totkey+i] = ((ParticleCacheKey*)buf->data) + i*steps;
+
+               totkey += totbufkey;
+               BLI_addtail(bufs, buf);
+       }
+
+       return cache;
+}
+
+static void psys_free_path_cache_buffers(ParticleCacheKey **cache, ListBase *bufs)
+{
+       LinkData *buf;
+
+       if(cache)
+               MEM_freeN(cache);
+
+       for(buf= bufs->first; buf; buf=buf->next)
+               MEM_freeN(buf->data);
+       BLI_freelistN(bufs);
+}
+
 /************************************************/
 /*                     Getting stuff                                           */
 /************************************************/
@@ -306,27 +349,16 @@ void free_keyed_keys(ParticleSystem *psys)
 }
 void free_child_path_cache(ParticleSystem *psys)
 {
-       if(psys->childcache){
-               if(psys->childcache[0])
-                       MEM_freeN(psys->childcache[0]);
-
-               MEM_freeN(psys->childcache);
-
-               psys->childcache = NULL;
-               psys->totchildcache = 0;
-       }
+       psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs);
+       psys->childcache = NULL;
+       psys->totchildcache = 0;
 }
 void psys_free_path_cache(ParticleSystem *psys)
 {
-       if(psys->pathcache){
-               if(psys->pathcache[0])
-                       MEM_freeN(psys->pathcache[0]);
-
-               MEM_freeN(psys->pathcache);
+       psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs);
+       psys->pathcache= NULL;
+       psys->totcached= 0;
 
-               psys->pathcache = NULL;
-               psys->totcached = 0;
-       }
        free_child_path_cache(psys);
 }
 void psys_free_children(ParticleSystem *psys)
@@ -2257,10 +2289,9 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
        ParticleSettings *part = psys->part;
        ParticleThread *pthreads;
        ParticleThreadContext *ctx;
-       ParticleCacheKey **cache, *tcache;
+       ParticleCacheKey **cache;
        ListBase threads;
        int i, totchild, totparent, totthread;
-       unsigned long totchildstep;
 
        pthreads= psys_threads_create(ob, psys);
 
@@ -2279,13 +2310,7 @@ void psys_cache_child_paths(Object *ob, ParticleSystem *psys, float cfra, int ed
        else {
                /* clear out old and create new empty path cache */
                free_child_path_cache(psys);
-
-               cache = psys->childcache = MEM_callocN(totchild*sizeof(void *), "Child path cache array");
-               totchildstep= totchild*(ctx->steps + 1);
-               tcache = MEM_callocN(totchildstep*sizeof(ParticleCacheKey), "Child path cache");
-               for(i=0; i<totchild; i++)
-                       cache[i] = tcache + i * (ctx->steps + 1);
-
+               psys->childcache= psys_alloc_path_cache_buffers(&psys->childcachebufs, totchild, ctx->steps+1);
                psys->totchildcache = totchild;
        }
 
@@ -2372,12 +2397,8 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
        else {
                /* clear out old and create new empty path cache */
                psys_free_path_cache(psys);
-
-               /* allocate cache array for fast access and set pointers to contiguous mem block */
-               cache = psys->pathcache = MEM_callocN(MAX2(1, totpart) * sizeof(void *), "Path cache array");
-               cache[0] = MEM_callocN(totpart * (steps + 1) * sizeof(ParticleCacheKey), "Path cache");
-               for(i=1; i<totpart; i++)
-                       cache[i] = cache[0] + i * (steps + 1);
+               cache= psys_alloc_path_cache_buffers(&psys->pathcachebufs, totpart, steps+1);
+               psys->pathcache= cache;
        }
 
        if(edit==NULL && psys->soft && psys->softflag & OB_SB_ENABLE)
index 596c381b8964cdad9b3510ebcc18563af68ec74e..8dd3b1d0324c0bc1c100cee20c0ff34b99914693 100644 (file)
@@ -46,6 +46,7 @@
 #include "DNA_curve_types.h"
 #include "DNA_group_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_sph_types.h"
 #include "DNA_texture_types.h"
 
 #include "BLI_rand.h"
@@ -74,6 +75,7 @@
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_scene.h"
+#include "BKE_sph.h"
 
 #include "BSE_headerbuttons.h"
 
@@ -4634,6 +4636,50 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
                snprintf(debugStrBuffer,256,"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d  \n", psys->totpart,activeParts,fileParts,readMask);
                elbeemDebugOut(debugStrBuffer);
        } // fluid sim particles done
+       else
+       {
+               // check for sph modifier
+               SphModifierData *sphmd = (SphModifierData *)modifiers_findByType(ob, eModifierType_Sph);
+               
+               // check for an sph object
+               if(sphmd)
+               {       
+                       // check for existing coordinates
+                       if(sphmd->sim_parms->co)
+                       {
+                               int i = 0;
+                               ParticleSettings *part = psys->part;
+                               ParticleData *pa=0;
+                               float null[3] = {0,0,0};
+                               
+                               if(ob==G.obedit) // off...
+                                       return;
+                               
+                               part->totpart= sphmd->sim_parms->numpart;
+                               part->sta=part->end = 1.0f;
+                               part->lifetime = G.scene->r.efra + 1;
+
+                               /* initialize particles */
+                               realloc_particles(ob, psys, part->totpart);
+                               initialize_all_particles(ob, psys, 0);
+                               
+                               printf("sphmd->sim_parms->numpart: %ld\n", sphmd->sim_parms->numpart);
+                               
+                               for(i = 0, pa=psys->particles; i < sphmd->sim_parms->numpart; i++, pa++)
+                               {
+                                       pa->size = 0.01f;
+                                       VECCOPY(pa->state.co, sphmd->sim_parms->co + i*3);
+                                       VECCOPY(pa->state.vel, null);
+                                       
+                                       pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
+                                       pa->state.rot[0] = 1.0;
+                                       pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0;
+
+                                       pa->alive = PARS_ALIVE;
+                               }
+                       }
+               }
+       }
        #endif // DISABLE_ELBEEM
 }
 
index 6798c3c47b70bf0e9ed88a91ec0ad566f8281bb7..2898dca767c66406703d4f706d96bd5318885f47 100644 (file)
@@ -67,6 +67,7 @@
 #include "BKE_global.h"
 #include "BKE_group.h"
 #include "BKE_ipo.h"
+#include "BKE_idprop.h"
 #include "BKE_image.h"
 #include "BKE_key.h"
 #include "BKE_library.h"
@@ -149,6 +150,11 @@ void free_scene(Scene *sce)
                MEM_freeN(sce->r.qtcodecdata);
                sce->r.qtcodecdata = NULL;
        }
+       if (sce->r.ffcodecdata.properties) {
+               IDP_FreeProperty(sce->r.ffcodecdata.properties);
+               MEM_freeN(sce->r.ffcodecdata.properties);
+               sce->r.ffcodecdata.properties = NULL;
+       }
        
        BLI_freelistN(&sce->markers);
        BLI_freelistN(&sce->transform_spaces);
index e79e36a14987e7d4ec52b9360fb9078417be8bec..c95e3d2044259fc9f5e5c0cdcc73db79778b4515 100644 (file)
@@ -33,6 +33,7 @@
 #include <ffmpeg/avcodec.h>
 #include <ffmpeg/rational.h>
 #include <ffmpeg/swscale.h>
+#include <ffmpeg/opt.h>
 
 #if LIBAVFORMAT_VERSION_INT < (49 << 16)
 #define FFMPEG_OLD_FRAME_RATE 1
@@ -58,6 +59,7 @@
 
 #include "BKE_bad_level_calls.h"
 #include "BKE_global.h"
+#include "BKE_idprop.h"
 
 #include "IMB_imbuf_types.h"
 #include "IMB_imbuf.h"
@@ -224,6 +226,10 @@ static const char** get_file_extensions(int format)
                static const char * rv[] = { ".flv", NULL };
                return rv;
        }
+       case FFMPEG_MKV: {
+               static const char * rv[] = { ".mkv", NULL };
+               return rv;
+       }
        default:
                return NULL;
        }
@@ -337,6 +343,75 @@ static AVFrame* generate_video_frame(uint8_t* pixels)
        return current_frame;
 }
 
+static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
+{
+       char name[128];
+       char * param;
+       const AVOption * rv = NULL;
+
+       fprintf(stderr, "FFMPEG expert option: %s: ", prop->name);
+
+       strncpy(name, prop->name, 128);
+
+       param = strchr(name, ':');
+
+       if (param) {
+               *param++ = 0;
+       }
+
+       switch(prop->type) {
+       case IDP_STRING:
+               fprintf(stderr, "%s.\n", IDP_String(prop));
+               rv = av_set_string(c, prop->name, IDP_String(prop));
+               break;
+       case IDP_FLOAT:
+               fprintf(stderr, "%g.\n", IDP_Float(prop));
+               rv = av_set_double(c, prop->name, IDP_Float(prop));
+               break;
+       case IDP_INT:
+               fprintf(stderr, "%d.\n", IDP_Int(prop));
+               
+               if (param) {
+                       if (IDP_Int(prop)) {
+                               rv = av_set_string(c, name, param);
+                       } else {
+                               return;
+                       }
+               } else {
+                       rv = av_set_int(c, prop->name, IDP_Int(prop));
+               }
+               break;
+       }
+
+       if (!rv) {
+               fprintf(stderr, "ffmpeg-option not supported: %s! Skipping.\n",
+                       prop->name);
+       }
+}
+
+static void set_ffmpeg_properties(AVCodecContext* c, const char * prop_name)
+{
+       IDProperty * prop;
+       void * iter;
+       IDProperty * curr;
+
+       if (!G.scene->r.ffcodecdata.properties) {
+               return;
+       }
+       
+       prop = IDP_GetPropertyFromGroup(
+               G.scene->r.ffcodecdata.properties, (char*) prop_name);
+       if (!prop) {
+               return;
+       }
+
+       iter = IDP_GetGroupIterator(prop);
+
+       while ((curr = IDP_GroupIterNext(iter)) != NULL) {
+               set_ffmpeg_property_option(c, curr);
+       }
+}
+
 /* prepare a video stream for the output file */
 
 static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of,
@@ -423,13 +498,18 @@ static AVStream* alloc_video_stream(int codec_id, AVFormatContext* of,
        }
        
        /* Determine whether we are encoding interlaced material or not */
-       if (G.scene->r.mode & (1 << 6)) {
+       if (G.scene->r.mode & R_FIELDS) {
                fprintf(stderr, "Encoding interlaced video\n");
                c->flags |= CODEC_FLAG_INTERLACED_DCT;
                c->flags |= CODEC_FLAG_INTERLACED_ME;
-       }       
-       c->sample_aspect_ratio.num = G.scene->r.xasp;
-       c->sample_aspect_ratio.den = G.scene->r.yasp;
+       }
+
+       /* xasp & yasp got float lately... */
+
+       c->sample_aspect_ratio = av_d2q(
+               ((double) G.scene->r.xasp / (double) G.scene->r.yasp), 255);
+
+       set_ffmpeg_properties(c, "video");
        
        if (avcodec_open(c, codec) < 0) {
                error("Couldn't initialize codec");
@@ -474,6 +554,9 @@ static AVStream* alloc_audio_stream(int codec_id, AVFormatContext* of)
                error("Couldn't find a valid audio codec");
                return NULL;
        }
+
+       set_ffmpeg_properties(c, "audio");
+
        if (avcodec_open(c, codec) < 0) {
                error("Couldn't initialize audio codec");
                return NULL;
index 5b4e380f88ea6853869c7f5591c75df4143cf114..9ed23bc32b6bc35e020bb4033be428d96eea48eb 100644 (file)
@@ -96,7 +96,7 @@ float CalcNormFloat4(float *v1, float *v2, float *v3, float *v4, float *n);
 void CalcNormLong(int *v1, int *v2, int *v3, float *n);
 /* CalcNormShort: is ook uitprodukt - (translates as 'is also out/cross product') */
 void CalcNormShort(short *v1, short *v2, short *v3, float *n);
-
+float power_of_2(float val);
 
 /**
  * @section Euler conversion routines
index f3aa69d77ffa7f21ed38d54ce9bfeea0557080e6..abbd17c36354a3249b939bb0d8224ea3a14389d9 100644 (file)
@@ -86,6 +86,9 @@ void                          BLI_edgehashIterator_getKey             (EdgeHashIterator *ehi, int *v0_r, int *v1
        /* Retrieve the value from an iterator. */
 void*                          BLI_edgehashIterator_getValue   (EdgeHashIterator *ehi);
 
+       /* Set the value for an iterator. */
+void                           BLI_edgehashIterator_setValue   (EdgeHashIterator *ehi, void *val);
+
        /* Steps the iterator to the next index. */
 void                           BLI_edgehashIterator_step               (EdgeHashIterator *ehi);
 
index 51f87b26aafd2ef826d11f0af9e64f7f025c944a..3261984da7604f7e97389536e6138a44266d9e54 100644 (file)
@@ -21,7 +21,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): Daniel (Genscher)
+ * Contributor(s): Daniel Genrich, Jose Pinto
  *
  * ***** END GPL LICENSE BLOCK *****
  */
index 8be52854a7bf29e79db38a8284714f622fce9539..6a1abb5d8ad1b6b5d8a896335ad5047dea8677b2 100644 (file)
@@ -25,7 +25,7 @@
 *
 * The Original Code is: all of this file.
 *
-* Contributor(s): Daniel Genrich
+* Contributor(s): Daniel Genrich, Jose Pinto
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
@@ -60,7 +60,6 @@ struct BVHTree
 {
        BVHNode **nodes;
        BVHNode *nodearray; /* pre-alloc branch nodes */
-       int     *orig_index; /* mapping for orig_index to node_index */
        float   epsilon; /* epslion is used for inflation of the k-dop     */
        int     totleaf; // leafs
        int     totbranch;
@@ -253,7 +252,6 @@ void BLI_bvhtree_free(BVHTree *tree)
        {
                MEM_freeN(tree->nodes);
                MEM_freeN(tree->nodearray);
-               MEM_freeN(tree->orig_index);
                MEM_freeN(tree);
        }
 }
@@ -292,16 +290,6 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
                        return NULL;
                }
                
-               tree->orig_index = (int *)MEM_callocN(sizeof(int)*(numbranches+maxsize + tree_type), "BVHIndexArray");
-               
-               if(!tree->orig_index)
-               {
-                       MEM_freeN(tree);
-                       MEM_freeN(tree->nodes);
-                       MEM_freeN(tree->nodearray);
-                       return NULL;
-               }
-               
                tree->epsilon = epsilon;
                tree->tree_type = tree_type; 
                tree->axis = axis;
@@ -559,12 +547,6 @@ void BLI_bvhtree_balance(BVHTree *tree)
        // create + balance tree
        bvh_div_nodes(tree, tree->nodes[tree->totleaf], 0, tree->totleaf, 0);
        
-       // put indices into array for O(1) access
-       for(i = 0; i < tree->totleaf; i++)
-       {
-               tree->orig_index[tree->nodes[i]->index] = i;
-       }
-       
        verify_tree(tree);
 }
 
@@ -741,7 +723,7 @@ int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_movin
        if(index > tree->totleaf)
                return 0;
        
-       node = tree->nodes[tree->orig_index[index]];
+       node = tree->nodearray + index;
        
        create_kdop_hull(tree, node, co, numpoints, 0);
        
index 19a8d4f51527e9b533f05c5b6a4ffd08edddc744..48a149f4b3a1c2e49894eca3be2ab31589e3165b 100644 (file)
@@ -4345,3 +4345,8 @@ void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2,
        if ((ct[0]*n[0] + ct[1]*n[1] + ct[2]*n[2]) < 0.0f)
                VecMulf(tang, -1.0f);
 }
+
+/* used for zoom values*/
+float power_of_2(float val) {
+       return pow(2, ceil(log(val) / log(2)));
+}
index 6aa0ded63b900115ac8167e2937bf79229aa76d3..3e1c8afb7a8a26fe0f56049fec3cd9d07c774ce4 100644 (file)
@@ -200,6 +200,11 @@ void *BLI_edgehashIterator_getValue(EdgeHashIterator *ehi) {
        return ehi->curEntry?ehi->curEntry->val:NULL;
 }
 
+void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val) {
+       if(ehi->curEntry)
+               ehi->curEntry->val= val;
+}
+
 void BLI_edgehashIterator_step(EdgeHashIterator *ehi) {
        if (ehi->curEntry) {
         ehi->curEntry= ehi->curEntry->next;
index e3649a0cc43fe595e05f7998c42545584daba92c..2f98a305f1c5129c57d8f9390545bdd796246bd2 100644 (file)
@@ -2615,6 +2615,8 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
                psys->edit = 0;
                psys->pathcache = 0;
                psys->childcache = 0;
+               psys->pathcachebufs.first = psys->pathcachebufs.last = 0;
+               psys->childcachebufs.first = psys->childcachebufs.last = 0;
                psys->reactevents.first = psys->reactevents.last = 0;
 
                psys->pointcache= newdataadr(fd, psys->pointcache);
@@ -3593,7 +3595,16 @@ static void direct_link_scene(FileData *fd, Scene *sce)
        if (sce->r.qtcodecdata) {
                sce->r.qtcodecdata->cdParms = newdataadr(fd, sce->r.qtcodecdata->cdParms);
        }
-       
+       if (sce->r.ffcodecdata.properties) {
+               sce->r.ffcodecdata.properties = newdataadr(
+                       fd, sce->r.ffcodecdata.properties);
+               if (sce->r.ffcodecdata.properties) { 
+                       IDP_DirectLinkProperty(
+                               sce->r.ffcodecdata.properties, 
+                               (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+               }
+       }
+
        link_list(fd, &(sce->markers));
        link_list(fd, &(sce->transform_spaces));
        link_list(fd, &(sce->r.layers));
index 47ccd333dd9eadedfb62db4595b762654b421dd7..b4a9f225470acbeb52d7b3211c15288b433cfc9f 100644 (file)
@@ -1532,6 +1532,9 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                        writestruct(wd, DATA, "QuicktimeCodecData", 1, sce->r.qtcodecdata);
                        if (sce->r.qtcodecdata->cdParms) writedata(wd, DATA, sce->r.qtcodecdata->cdSize, sce->r.qtcodecdata->cdParms);
                }
+               if (sce->r.ffcodecdata.properties) {
+                       IDP_WriteProperty(sce->r.ffcodecdata.properties, wd);
+               }
 
                /* writing dynamic list of TimeMarkers to the blend file */
                for(marker= sce->markers.first; marker; marker= marker->next)
index fb6b65c39729cc3946d125cf6c156f0025c9a4c6..58b344981cae02d8bda0d313781e7e83965cec97 100644 (file)
@@ -32,6 +32,7 @@
 
 struct MTFace;
 struct EditFace;
+struct EditEdge;
 struct Mesh;
 struct MCol;
 
@@ -53,6 +54,8 @@ void uv_autocalc_tface(void);
 void set_texturepaint(void);
 void get_same_uv(void);  
 void seam_mark_clear_tface(short mode);
-
+int edgetag_shortest_path(struct EditEdge *source, struct EditEdge *target);
+void edgetag_context_set(struct EditEdge *eed, int val);
+int edgetag_context_check(struct EditEdge *eed);
 #endif /* BDR_EDITFACE_H */
 
index 17311ab1489d79f6058ad72f1299036eb20e9a9d..462075cdf3dfa71d7eb6841bfa1a33cf5497f243 100644 (file)
@@ -39,5 +39,7 @@ void set_special_seq_update(int val);
 
 void seq_viewmove(SpaceSeq *sseq);
 void seq_reset_imageofs(SpaceSeq *sseq);
+void seq_viewzoom(unsigned short event, int invert);
+void seq_home(void);
 #endif
 
index 86f84c1e0284bdd4a01e39b1a4dca0368f381c4b..ca9f3d6a378f4cd9a7e6baf8812f1c3f263ff19a 100644 (file)
@@ -260,5 +260,6 @@ int EM_vertColorCheck(void); /* can we edit colors for this mesh?*/
 
 void EM_set_actFace(struct EditFace *efa);
 struct EditFace * EM_get_actFace(int sloppy);
+int EM_get_actSelection(struct EditSelection *ese);
 
 #endif
index 24747b9f220c96373885d4ba7497a0e2d0f5ed8c..fbd4e4ecd91b642532bf5e8c32b1bc67ef45637b 100644 (file)
@@ -164,6 +164,7 @@ struct AutoComplete;
 #define BUT_TOGDUAL (33<<9)
 #define ICONTOGN (34<<9)
 #define FTPREVIEW (35<<9)
+#define NUMABS (36<<9)
 #define BUTTYPE        (63<<9)
 
 
index 8122cdd9cc7b898932249147c89ad7d2f07a9a8e..4f62cd084cc9b0ca0095635d1ab4d3276ea15bb5 100644 (file)
@@ -168,27 +168,27 @@ typedef struct ParticleSettings {
        struct PartDeflect *pd;
 } ParticleSettings;
 
-typedef struct ParticleSystem{
+typedef struct ParticleSystem{                         /* note, make sure all (runtime) are NULL's in copy_particlesystem */
        struct ParticleSystem *next, *prev;
 
-       ParticleSettings *part;
+       ParticleSettings *part;                                 /* particle settings */
 
-       ParticleData *particles;
+       ParticleData *particles;                                /* (parent) particles */
+       ChildParticle *child;                                   /* child particles */
 
-       ChildParticle *child;
+       struct ParticleEdit *edit;                              /* particle editmode (runtime) */
 
-       struct ParticleEdit *edit;
+       struct ParticleCacheKey **pathcache;    /* path cache (runtime) */
+       struct ParticleCacheKey **childcache;   /* child cache (runtime) */
+       ListBase pathcachebufs, childcachebufs; /* buffers for the above */
 
-       struct ParticleCacheKey **pathcache;
-       struct ParticleCacheKey **childcache;
-
-       struct SoftBody *soft;
+       struct SoftBody *soft;                                  /* hair softbody */
 
        struct Object *target_ob;
        struct Object *keyed_ob;
        struct Object *lattice;
 
-       struct ListBase effectors, reactevents;
+       struct ListBase effectors, reactevents; /* runtime */
        
        float imat[4][4];       /* used for duplicators */
        float cfra;
@@ -196,10 +196,10 @@ typedef struct ParticleSystem{
        int flag, totpart, totchild, totcached, totchildcache, rt;
        short recalc, target_psys, keyed_psys, totkeyed, softflag, bakespace;
 
-       char bb_uvname[3][32];
+       char bb_uvname[3][32];                                  /* billboard uv name */
 
        /* if you change these remember to update array lengths to PSYS_TOT_VG! */
-       short vgroup[11], vg_neg, rt3[2];
+       short vgroup[12], vg_neg, rt3;                  /* vertex groups */
 
        /* temporary storage during render */
        void *renderdata;
index e0e8c351d2ce2235033a401113fbcb747140f4c7..7b1b979b7777a7fa4489f9071d81a50246aa14e4 100644 (file)
@@ -98,6 +98,7 @@ typedef struct FFMpegCodecData {
        int rc_buffer_size;
        int mux_packet_size;
        int mux_rate;
+       IDProperty *properties;
 } FFMpegCodecData;
 
 
@@ -437,7 +438,9 @@ typedef struct ToolSettings {
        char  skgen_postpro_passes;
        char  skgen_subdivisions[3];
        
-       char pad3[5];
+       /* Alt+RMB option */
+       char edge_mode;
+       char pad3[4];
 } ToolSettings;
 
 /* Used by all brushes to store their properties, which can be directly set
@@ -783,6 +786,13 @@ typedef struct Scene {
 #define UVCALC_FILLHOLES                       1
 #define UVCALC_NO_ASPECT_CORRECT       2       /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
 
+/* toolsettings->edge_mode */
+#define EDGE_MODE_SELECT                               0
+#define EDGE_MODE_TAG_SEAM                             1
+#define EDGE_MODE_TAG_SHARP                            2
+#define EDGE_MODE_TAG_CREASE                   3
+#define EDGE_MODE_TAG_BEVEL                            4
+
 /* toolsettings->particle flag */
 #define PE_KEEP_LENGTHS                        1
 #define PE_LOCK_FIRST                  2
index 67b04750056975ae956943c9f54cc9abc9e2c5e0..f5b6edcea80beaf00147e0d4c38e0d577e62b931 100644 (file)
@@ -44,18 +44,22 @@ static bNodeSocketType cmp_node_displace_out[]= {
        {       -1, 0, ""       }
 };
 
+static float *vecbuf_get_pixel(CompBuf *vecbuf, float *veccol, int x, int y)
+{
+       /* the x-xrad stuff is a bit weird, but i seem to need it otherwise 
+        * my returned pixels are offset weirdly */
+       return compbuf_get_pixel(vecbuf, veccol, x-vecbuf->xrad, y-vecbuf->yrad, vecbuf->xrad, vecbuf->yrad);
+}
+
 static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *veccol, float *xscale, float *yscale)
 {
        ImBuf *ibuf;
-       int x, y, vx, vy, sx, sy;
        float dx=0.0, dy=0.0;
        float dspx, dspy;
-       float uv[2];
-
-       float *out= stackbuf->rect, *vec=vecbuf->rect, *in= cbuf->rect;
+       float uv[2], col[4], colnext[4], colprev[4];
        float *vp, *vpnext, *vpprev;
-       
-       int row = 3*vecbuf->x;
+       float *out= stackbuf->rect, *vec=vecbuf->rect, *in= cbuf->rect;
+       int x, y, vx, vy, sx, sy;
        
        /* ibuf needed for sampling */
        ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0, 0);
@@ -65,13 +69,15 @@ static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float
        
        sx= stackbuf->x;
        sy= stackbuf->y;
+
+       QUATCOPY(col, veccol);
+       QUATCOPY(colnext, veccol);
+       QUATCOPY(colprev, veccol);
        
        for(y=0; y<sy; y++) {
                for(x= 0; x< sx; x++, out+=4, in+=4, vec+=3) {
                        
-                       /* the x-xrad stuff is a bit weird, but i seem to need it otherwise 
-                        * my returned pixels are offset weirdly */
-                       vp = compbuf_get_pixel(vecbuf, veccol, x-vecbuf->xrad, y-vecbuf->yrad, vecbuf->xrad, vecbuf->yrad);
+                       vp = vecbuf_get_pixel(vecbuf, col, x, y);
 
                        /* this happens in compbuf_get_pixel, need to make sure the following
                         * check takes them into account */
@@ -87,20 +93,26 @@ static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float
                        uv[1] = dspy / (float)sy;
                
                        if(vx>0 && vx< vecbuf->x-1 && vy>0 && vy< vecbuf->y-1)  {
-                               vpnext = vp+row;
-                               vpprev = vp-row;
-                       
-                               /* adaptive sampling, X channel */
-                               dx= 0.5f*(fabs(vp[0]-vp[-3]) + fabs(vp[0]-vp[3]));
-                               
-                               dx+= 0.25f*(fabs(vp[0]-vpprev[-3]) + fabs(vp[0]-vpnext[-3]));
-                               dx+= 0.25f*(fabs(vp[0]-vpprev[+3]) + fabs(vp[0]-vpnext[+3]));
-                               
-                               /* adaptive sampling, Y channel */
-                               dy= 0.5f*(fabs(vp[1]-vp[-row+1]) + fabs(vp[1]-vp[row+1]));
-                                                
-                               dy+= 0.25f*(fabs(vp[1]-vpprev[+1-3]) + fabs(vp[1]-vpnext[+1-3]));
-                               dy+= 0.25f*(fabs(vp[1]-vpprev[+1+3]) + fabs(vp[1]-vpnext[+1+3]));
+                               /* adaptive sampling, X and Y channel.
+                                * we call vecbuf_get_pixel for every pixel since the input
+                                * might be a procedural, and then we can't use offsets */
+                               vpprev = vecbuf_get_pixel(vecbuf, colprev, x-1, y);
+                               vpnext = vecbuf_get_pixel(vecbuf, colnext, x+1, y);
+                               dx= 0.5f*(fabs(vp[0]-vpprev[0]) + fabs(vp[0]-vpnext[0]));
+
+                               vpprev = vecbuf_get_pixel(vecbuf, colprev, x, y-1);
+                               vpnext = vecbuf_get_pixel(vecbuf, colnext, x, y+1);
+                               dy= 0.5f*(fabs(vp[1]-vpnext[1]) + fabs(vp[1]-vpprev[1]));
+
+                               vpprev = vecbuf_get_pixel(vecbuf, colprev, x-1, y-1);
+                               vpnext = vecbuf_get_pixel(vecbuf, colnext, x-1, y+1);
+                               dx+= 0.25f*(fabs(vp[0]-vpprev[0]) + fabs(vp[0]-vpnext[0]));
+                               dy+= 0.25f*(fabs(vp[1]-vpprev[1]) + fabs(vp[1]-vpnext[1]));
+
+                               vpprev = vecbuf_get_pixel(vecbuf, colprev, x+1, y-1);
+                               vpnext = vecbuf_get_pixel(vecbuf, colnext, x+1, y+1);
+                               dx+= 0.25f*(fabs(vp[0]-vpprev[0]) + fabs(vp[0]-vpnext[0]));
+                               dy+= 0.25f*(fabs(vp[1]-vpprev[1]) + fabs(vp[1]-vpnext[1]));
                                
                                /* scaled down to prevent blurriness */
                                /* 8: magic number, provides a good level of sharpness without getting too aliased */
index eeddb4ce756527a9907d9ffa11a4cd5260b31c5f..92614d1cc6ab160acd2d34a47105f3badb1fe8e9 100644 (file)
@@ -52,9 +52,7 @@ static void do_hue_sat_fac(bNode *node, float *out, float *in, float *fac)
                hsv[0]+= (nhs->hue - 0.5f);
                if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
                hsv[1]*= nhs->sat;
-               if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
                hsv[2]*= nhs->val;
-               if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
                hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
                
                out[0]= mfac*in[0] + *fac*col[0];
index 8c07a2d1dc869667e28ba49514b48423d92efc17..67dfc6190802936c645fc5e85a5d817588bc3611 100644 (file)
@@ -54,9 +54,7 @@ static void do_hue_sat_fac(bNode *node, float *out, float *hue, float *sat, floa
                hsv[0]+= (*hue - 0.5f);
                if(hsv[0]>1.0) hsv[0]-=1.0; else if(hsv[0]<0.0) hsv[0]+= 1.0;
                hsv[1]*= *sat;
-               if(hsv[1]>1.0) hsv[1]= 1.0; else if(hsv[1]<0.0) hsv[1]= 0.0;
                hsv[2]*= *val;
-               if(hsv[2]>1.0) hsv[2]= 1.0; else if(hsv[2]<0.0) hsv[2]= 0.0;
                hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2);
                
                out[0]= mfac*in[0] + *fac*col[0];
index ffdb593767a84016df681129532c1e5c993e272f..257203908b1d671738cc5e00c47ca50eb5c6045b 100644 (file)
@@ -435,19 +435,24 @@ void BPY_rebuild_syspath( void )
        if(U.pythondir[0] != '\0' ) {
                char modpath[FILE_MAX];
                int upyslen = strlen(U.pythondir);
-
+               BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
+               
                /* check if user pydir ends with a slash and, if so, remove the slash
                 * (for eventual implementations of c library's stat function that might
                 * not like it) */
-               if (upyslen > 2) { /* avoids doing anything if dir == '//' */
-                       BLI_add_slash(U.pythondir);
+#ifdef WIN32
+               if (upyslen > 3) {
+#else
+               if (upyslen > 1) {
+#endif
+                       if (dirpath[upyslen-1] == '\\' || dirpath[upyslen-1] == '/') {
+                               dirpath[upyslen-1] = '\0';
+                       }
                }
 
-               BLI_strncpy(dirpath, U.pythondir, FILE_MAX);
                BLI_convertstringcode(dirpath, G.sce);
                syspath_append(dirpath);        /* append to module search path */
-
-               BLI_make_file_string("/", modpath, dirpath, "bpymodules");
+               BLI_join_dirfile( modpath, dirpath, "bpymodules" );
                if (BLI_exists(modpath)) syspath_append(modpath);
        }
        
@@ -783,7 +788,6 @@ int BPY_run_script(Script *script)
        Text *text = NULL;
        BPy_constant *info;
        int len;
-       char *buffer=NULL, *s;
        
        FILE *fp = NULL;
        
@@ -864,7 +868,6 @@ int BPY_run_script(Script *script)
                printf("Oops - weakref dict\n");
                free_libblock( &G.main->script, script );
                ReleaseGlobalDictionary( py_dict );
-               MEM_freeN( buffer );
                PyGILState_Release(gilstate);
                return 0;
        }
@@ -886,41 +889,41 @@ int BPY_run_script(Script *script)
                * 'FILE structs for different C libraries can be different and 
                * incompatible'.
                * So now we load the script file data to a buffer */
-       
+               char *buffer=NULL, *buffer_ofs=NULL, *b_to, *b_from;
+               
                fseek( fp, 0L, SEEK_END );
                len = ftell( fp );
                fseek( fp, 0L, SEEK_SET );
        
-               buffer = MEM_mallocN( len + 2, "pyfilebuf" );   /* len+2 to add '\n\0' */
+               buffer = buffer_ofs = MEM_mallocN( len + 2, "pyfilebuf" );      /* len+2 to add '\n\0' */
                len = fread( buffer, 1, len, fp );
        
                buffer[len] = '\n';     /* fix syntax error in files w/o eol */
                buffer[len + 1] = '\0';
-       
-               /* fast clean-up of dos cr/lf line endings: change '\r' to space */
-       
-               /* we also have to check for line splitters: '\\' */
-               /* to avoid possible syntax errors on dos files on win */
-               /**/
-                       /* but first make sure we won't disturb memory below &buffer[0]: */
-                       if( *buffer == '\r' )
-                       *buffer = ' ';
-       
-               /* now handle the whole buffer */
-               for( s = buffer + 1; *s != '\0'; s++ ) {
-                       if( *s == '\r' ) {
-                               if( *( s - 1 ) == '\\' ) {      /* special case: long lines split with '\': */
-                                       *( s - 1 ) = ' ';       /* we write ' \', because '\ ' is a syntax error */
-                                       *s = '\\';
-                               } else
-                                       *s = ' ';       /* not a split line, just replace '\r' with ' ' */
+               
+               
+               /* fast clean-up of dos cr/lf line endings, remove convert '\r\n's to '\n' */
+               if (*buffer_ofs == '\r' && *(buffer_ofs+1) == '\n') {
+                       buffer_ofs++;
+               }
+               b_from = b_to = buffer_ofs;
+               
+               while(*b_from != '\0') {
+                       if (*b_from == '\r' && *( b_from+1 ) == '\n') {
+                               b_from++;
                        }
+                       if (b_from != b_to) {
+                               *b_to = *b_from;
+                       }
+                       b_to++;
+                       b_from++;
                }
-       
-               fclose( fp );
+               *b_to = '\0';
+               /* done cleaning the string */
                
+               fclose( fp );
                
-               py_res = PyRun_String( buffer, Py_file_input, py_dict, py_dict );
+               py_res = PyRun_String( buffer_ofs, Py_file_input, py_dict, py_dict );
                MEM_freeN( buffer );
        }
 
index 4fc68d138e06b9e60972b4dd3a219a99a58e5464..6fce086418988143a74bc80a465a53781cef088b 100644 (file)
@@ -96,6 +96,7 @@ struct ID; /*keep me up here */
 #include "Window.h"
 #include "World.h"
 #include "Types.h"
+#include "Particle.h"
 
 /**********************************************************/
 /* Python API function prototypes for the Blender module.      */
@@ -1074,6 +1075,7 @@ void M_Blender_Init(void)
        PyDict_SetItemString(dict, "Node", Node_Init());
        PyDict_SetItemString(dict, "Noise", Noise_Init());
        PyDict_SetItemString(dict, "Object", Object_Init());
+       PyDict_SetItemString(dict, "Particle", ParticleSys_Init());
        PyDict_SetItemString(dict, "Group", Group_Init());
        PyDict_SetItemString(dict, "Registry", Registry_Init());
        PyDict_SetItemString(dict, "Scene", Scene_Init());
index 4d8caf5a55ebdc735b60f9e09bed6f5a088d2684..82f99adcdb1ee9ab76fdfd6bd75782d49136880d 100644 (file)
@@ -27,7 +27,7 @@
  *
  * Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
  * Joseph Gilbert, Stephen Swaney, Bala Gi, Campbell Barton, Johnny Matthews,
- * Ken Hughes, Alex Mole, Jean-Michel Soler
+ * Ken Hughes, Alex Mole, Jean-Michel Soler, Cedric Paille
  *
  * ***** END GPL LICENSE BLOCK *****
 */
@@ -68,6 +68,8 @@ struct rctf;
 #include "BKE_object.h"
 #include "BKE_key.h" /* for setting the activeShape */
 #include "BKE_displist.h"
+#include "BKE_pointcache.h"
+#include "BKE_particle.h"
 
 #include "BSE_editipo.h"
 #include "BSE_edit.h"
@@ -117,6 +119,7 @@ struct rctf;
 #include "EXPP_interface.h"
 #include "BIF_editkey.h"
 #include "IDProp.h"
+#include "Particle.h"
 
 /* Defines for insertIpoKey */
 
@@ -336,6 +339,9 @@ struct PyMethodDef M_Object_methods[] = {
 static int setupSB(Object* ob); /*Make sure Softbody Pointer is initialized */
 static int setupPI(Object* ob);
 
+static PyObject *Object_getParticleSys( BPy_Object * self );
+/* fixme Object_newParticleSys( self, default-partsys-name ) */
+static PyObject *Object_newParticleSys( BPy_Object * self );
 static PyObject *Object_buildParts( BPy_Object * self );
 static PyObject *Object_clearIpo( BPy_Object * self );
 static PyObject *Object_clrParent( BPy_Object * self, PyObject * args );
@@ -465,6 +471,10 @@ static PyObject *Object_upAxis(BPy_Object * self);
 /*****************************************************************************/
 static PyMethodDef BPy_Object_methods[] = {
        /* name, method, flags, doc */
+       {"getParticleSystems", ( PyCFunction ) Object_getParticleSys, METH_NOARGS,
+        "Return a list of particle systems"},
+       {"newParticleSystem", ( PyCFunction ) Object_newParticleSys, METH_NOARGS,
+        "Create and link a new particle system"},
        {"buildParts", ( PyCFunction ) Object_buildParts, METH_NOARGS,
         "Recalcs particle system (if any), (depricated, will always return an empty list in version 2.46)"},
        {"getIpo", ( PyCFunction ) Object_getIpo, METH_NOARGS,
@@ -1026,6 +1036,79 @@ static PyObject *M_Object_Duplicate( PyObject * self_unused,
 /* Python BPy_Object methods:                                  */
 /*****************************************************************************/
 
+PyObject *Object_getParticleSys( BPy_Object * self ){
+       ParticleSystem *blparticlesys = 0;
+       Object *ob = self->object;
+       PyObject *partsyslist,*current;
+
+       blparticlesys = ob->particlesystem.first;
+
+       partsyslist = PyList_New( 0 );
+
+       if (!blparticlesys)
+               return partsyslist;
+
+/* fixme:  for(;;) */
+       current = ParticleSys_CreatePyObject( blparticlesys, ob );
+       PyList_Append(partsyslist,current);
+
+       while((blparticlesys = blparticlesys->next)){
+               current = ParticleSys_CreatePyObject( blparticlesys, ob );
+               PyList_Append(partsyslist,current);
+       }
+
+       return partsyslist;
+}
+
+PyObject *Object_newParticleSys( BPy_Object * self ){
+       ParticleSystem *psys = 0;
+       ParticleSystem *rpsys = 0;
+       ModifierData *md;
+       ParticleSystemModifierData *psmd;
+       Object *ob = self->object;
+/*     char *name = NULL;  optional name param */
+       ID *id;
+       int nr;
+
+       id = (ID *)psys_new_settings("PSys", G.main);
+
+       psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+       psys->pointcache = BKE_ptcache_add();
+       psys->flag |= PSYS_ENABLED;
+       BLI_addtail(&ob->particlesystem,psys);
+
+       md = modifier_new(eModifierType_ParticleSystem);
+       sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+       psmd = (ParticleSystemModifierData*) md;
+       psmd->psys=psys;
+       BLI_addtail(&ob->modifiers, md);
+
+       psys->part=(ParticleSettings*)id;
+       psys->totpart=0;
+       psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+       psys->cfra=bsystem_time(ob,(float)G.scene->r.cfra+1,0.0);
+       rpsys = psys;
+
+       /* check need for dupliobjects */
+
+       nr=0;
+       for(psys=ob->particlesystem.first; psys; psys=psys->next){
+               if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
+                       nr++;
+       }
+       if(nr)
+               ob->transflag |= OB_DUPLIPARTS;
+       else
+               ob->transflag &= ~OB_DUPLIPARTS;
+
+       BIF_undo_push("Browse Particle System");
+
+       DAG_scene_sort(G.scene);
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+       return ParticleSys_CreatePyObject(rpsys,ob);
+}
+
 static PyObject *Object_buildParts( BPy_Object * self )
 {
        /* This is now handles by modifiers */
index 1de0360cd7779298e7174ee882d278ed2166e950..15307cc2be580c770cd94a6e04059f9af3729ad4 100644 (file)
  *
  * This is a new part of Blender.
  *
- * Contributor(s): Jacques Guignot, Jean-Michel Soler 
+ * Contributor(s): 
+ *    Original version: Jacques Guignot, Jean-Michel Soler
+ *    Rewrite :        Cedric Paille, Stephen Swaney, Joilnen Leite
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 
-#include "Particle.h" /*This must come first */
-
-#include "DNA_object_types.h"
-#include "BKE_effect.h"
-#include "BKE_global.h"
-#include "BKE_main.h"
+#include "Particle.h"
+#include "gen_utils.h"
 #include "BKE_object.h"
+#include "BKE_main.h"
+#include "BKE_particle.h"
+#include "BKE_global.h"
+#include "BKE_depsgraph.h"
+#include "BKE_modifier.h"
+#include "BKE_material.h"
+#include "BKE_utildefines.h"
+#include "BKE_pointcache.h"
+#include "BIF_editparticle.h"
+#include "BIF_space.h"
+#include "blendef.h"
+#include "DNA_modifier_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_material_types.h"
 #include "BLI_blenlib.h"
-#include "gen_utils.h"
+#include "mydevice.h"
+#include "Object.h"
+#include "Material.h"
+
+#include "MEM_guardedalloc.h"
+
+
+
+/* Type Methods */
+static PyObject *M_ParticleSys_New( PyObject * self, PyObject * args );
+static PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args );
+
+/* Particle Methods */
+static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args );
+static int Part_setSeed( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getSeed( BPy_PartSys * self );
+static int Part_setType( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getType( BPy_PartSys * self );
+static int Part_setResol( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getResol( BPy_PartSys * self );
+static int Part_setStart( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getStart( BPy_PartSys * self );
+static int Part_setEnd( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getEnd( BPy_PartSys * self );
+static int Part_setEditable( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getEditable( BPy_PartSys * self );
+static int Part_setAmount( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getAmount( BPy_PartSys * self );
+static int Part_setMultiReact( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getMultiReact( BPy_PartSys * self );
+static int Part_setReactShape( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getReactShape( BPy_PartSys * self );
+static int Part_setSegments( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getSegments( BPy_PartSys * self );
+static int Part_setLife( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getLife( BPy_PartSys * self );
+static int Part_setRandLife( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getRandLife( BPy_PartSys * self );
+static int Part_set2d( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_get2d( BPy_PartSys * self );
+static int Part_setMaxVel( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getMaxVel( BPy_PartSys * self );
+static int Part_setAvVel( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getAvVel( BPy_PartSys * self );
+static int Part_setLatAcc( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getLatAcc( BPy_PartSys * self );
+static int Part_setMaxTan( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getMaxTan( BPy_PartSys * self );
+static int Part_setGroundZ( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getGroundZ( BPy_PartSys * self );
+static int Part_setOb( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getOb( BPy_PartSys * self );
+static PyObject *Part_getRandEmission( BPy_PartSys * self );
+static int Part_setRandEmission( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getRandEmission( BPy_PartSys * self );
+static int Part_setParticleDist( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getParticleDist( BPy_PartSys * self );
+static int Part_setEvenDist( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getEvenDist( BPy_PartSys * self );
+static int Part_setDist( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getDist( BPy_PartSys * self );
+static int Part_setParticleDisp( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getParticleDisp( BPy_PartSys * self );
+static int Part_setJitterAmount( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getJitterAmount( BPy_PartSys * self );
+static int Part_setPF( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getPF( BPy_PartSys * self );
+static int Part_setInvert( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getInvert( BPy_PartSys * self );
+static int Part_setTargetOb( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getTargetOb( BPy_PartSys * self );
+static int Part_setTargetPsys( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getTargetPsys( BPy_PartSys * self );
+static int Part_setRenderObject( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getRenderObject( BPy_PartSys * self );
+static int Part_setStep( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getStep( BPy_PartSys * self );
+static int Part_setRenderStep( BPy_PartSys * self, PyObject * args );
+static PyObject *Part_getRenderStep( BPy_PartSys * self );
+static PyObject *Part_getDupOb( BPy_PartSys * self );
+static PyObject *Part_getDrawAs( BPy_PartSys * self );
+static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args );
 
 /*****************************************************************************/
-/* Python API function prototypes for the Particle module.                   */
+/* Python Effect_Type callback function prototypes:                           */
 /*****************************************************************************/
-PyObject *M_Particle_New( PyObject * self, PyObject * args );
-PyObject *M_Particle_Get( PyObject * self, PyObject * args );
+static PyObject *ParticleSys_repr( void );
 
 /*****************************************************************************/
-/* Python BPy_Particle methods declarations:                                 */
+/* The following string definitions are used for documentation strings.      */
+/* In Python these will be written to the console when doing a               */
+/* Blender.Particle.__doc__                                                  */
 /*****************************************************************************/
-PyObject *Effect_getType( BPy_Effect * self );
-PyObject *Effect_setType( BPy_Effect * self, PyObject * args );
-PyObject *Effect_getFlag( BPy_Effect * self );
-PyObject *Effect_setFlag( BPy_Effect * self, PyObject * args );
-PyObject *Particle_getSta( BPy_Particle * self );
-PyObject *Particle_setSta( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getEnd( BPy_Particle * self );
-PyObject *Particle_setEnd( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getLifetime( BPy_Particle * self );
-PyObject *Particle_setLifetime( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getNormfac( BPy_Particle * self );
-PyObject *Particle_setNormfac( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getObfac( BPy_Particle * self );
-PyObject *Particle_setObfac( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getRandfac( BPy_Particle * self );
-PyObject *Particle_setRandfac( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getTexfac( BPy_Particle * self );
-PyObject *Particle_setTexfac( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getRandlife( BPy_Particle * self );
-PyObject *Particle_setRandlife( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getNabla( BPy_Particle * self );
-PyObject *Particle_setNabla( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getVectsize( BPy_Particle * self );
-PyObject *Particle_setVectsize( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getTotpart( BPy_Particle * self );
-PyObject *Particle_setTotpart( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getTotkey( BPy_Particle * self );
-PyObject *Particle_setTotkey( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getSeed( BPy_Particle * self );
-PyObject *Particle_setSeed( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getForce( BPy_Particle * self );
-PyObject *Particle_setForce( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getMult( BPy_Particle * self );
-PyObject *Particle_setMult( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getLife( BPy_Particle * self );
-PyObject *Particle_setLife( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getMat( BPy_Particle * self );
-PyObject *Particle_setMat( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getChild( BPy_Particle * self );
-PyObject *Particle_setChild( BPy_Particle * self, PyObject * a );
-PyObject *Particle_getDefvec( BPy_Particle * self );
-PyObject *Particle_setDefvec( BPy_Particle * self, PyObject * a );
+static char M_ParticleSys_doc[] = "The Blender Effect module\n\n\
+This module provides access to **Object Data** in Blender.\n\
+Functions :\n\
+       Get(name) : retreives particle system (as list)  with the given name\n";
+static char M_ParticleSys_Get_doc[] = "xxx";
+static char M_ParticleSys_New_doc[] = "xxx";
 
 /*****************************************************************************/
-/* Python Particle_Type callback function prototypes:                        */
-/*****************************************************************************/
-void ParticleDeAlloc( BPy_Particle * msh );
-//int ParticlePrint (BPy_Particle *msh, FILE *fp, int flags);
-int ParticleSetAttr( BPy_Particle * msh, char *name, PyObject * v );
-PyObject *ParticleGetAttr( BPy_Particle * msh, char *name );
-PyObject *ParticleRepr( void );
-PyObject *ParticleCreatePyObject( struct Effect *particle );
-int ParticleCheckPyObject( PyObject * py_obj );
-struct Particle *ParticleFromPyObject( PyObject * py_obj );
-
+/* Python BPy_ParticleSys methods table:                                     */
 /*****************************************************************************/
-/* Python BPy_Particle methods table:                                        */
-/*****************************************************************************/
-static PyMethodDef BPy_Particle_methods[] = {
-       {"getType", ( PyCFunction ) Effect_getType,
-        METH_NOARGS, "() - Return Effect type"},
-       {"setType", ( PyCFunction ) Effect_setType,
-        METH_VARARGS, "() - Set Effect type"},
-       {"getFlag", ( PyCFunction ) Effect_getFlag,
-        METH_NOARGS, "() - Return Effect flag"},
-       {"setFlag", ( PyCFunction ) Effect_setFlag,
-        METH_VARARGS, "() - Set Effect flag"},
-       {"getStartTime", ( PyCFunction ) Particle_getSta,
-        METH_NOARGS, "()-Return particle start time"},
-       {"setStartTime", ( PyCFunction ) Particle_setSta, METH_VARARGS,
-        "()- Sets particle start time"},
-       {"getEndTime", ( PyCFunction ) Particle_getEnd,
-        METH_NOARGS, "()-Return particle end time"},
-       {"setEndTime", ( PyCFunction ) Particle_setEnd, METH_VARARGS,
-        "()- Sets particle end time"},
-       {"getLifetime", ( PyCFunction ) Particle_getLifetime,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setLifetime", ( PyCFunction ) Particle_setLifetime, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getNormfac", ( PyCFunction ) Particle_getNormfac,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setNormfac", ( PyCFunction ) Particle_setNormfac, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getObfac", ( PyCFunction ) Particle_getObfac,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setObfac", ( PyCFunction ) Particle_setObfac, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getRandfac", ( PyCFunction ) Particle_getRandfac,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setRandfac", ( PyCFunction ) Particle_setRandfac, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getTexfac", ( PyCFunction ) Particle_getTexfac,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setTexfac", ( PyCFunction ) Particle_setTexfac, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getRandlife", ( PyCFunction ) Particle_getRandlife,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setRandlife", ( PyCFunction ) Particle_setRandlife, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getNabla", ( PyCFunction ) Particle_getNabla,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setNabla", ( PyCFunction ) Particle_setNabla, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getVectsize", ( PyCFunction ) Particle_getVectsize,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setVectsize", ( PyCFunction ) Particle_setVectsize, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getTotpart", ( PyCFunction ) Particle_getTotpart,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setTotpart", ( PyCFunction ) Particle_setTotpart, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getTotkey", ( PyCFunction ) Particle_getTotkey,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setTotkey", ( PyCFunction ) Particle_setTotkey, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getSeed", ( PyCFunction ) Particle_getSeed,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setSeed", ( PyCFunction ) Particle_setSeed, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getForce", ( PyCFunction ) Particle_getForce,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setForce", ( PyCFunction ) Particle_setForce, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getMult", ( PyCFunction ) Particle_getMult,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setMult", ( PyCFunction ) Particle_setMult, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getLife", ( PyCFunction ) Particle_getLife,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setLife", ( PyCFunction ) Particle_setLife, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getMat", ( PyCFunction ) Particle_getMat,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setMat", ( PyCFunction ) Particle_setMat, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getChild", ( PyCFunction ) Particle_getChild,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setChild", ( PyCFunction ) Particle_setChild, METH_VARARGS,
-        "()- Sets particle life time "},
-       {"getDefvec", ( PyCFunction ) Particle_getDefvec,
-        METH_NOARGS, "()-Return particle life time"},
-       {"setDefvec", ( PyCFunction ) Particle_setDefvec, METH_VARARGS,
-        "()- Sets particle life time "},
-       
-       
+
+static PyMethodDef BPy_ParticleSys_methods[] = {
+       {"freeEdit", ( PyCFunction ) Part_freeEdit,
+        METH_NOARGS, "() - Free from edit mode"},
+       {"getLoc", ( PyCFunction ) Part_GetLoc,
+        METH_VARARGS, "() - Get particles location"},
+       {"getRot", ( PyCFunction ) Part_GetRot,
+        METH_VARARGS, "() - Get particles rotations (list of 4 floats quaternion)"},
+       {"getMat", ( PyCFunction ) Part_GetMat,
+        METH_NOARGS, "() - Get particles material"},
+       {"getSize", ( PyCFunction ) Part_GetSize,
+        METH_VARARGS, "() - Get particles size in a list"},
+       {"getAge", ( PyCFunction ) Part_GetAge,
+        METH_VARARGS, "() - Get particles life in a list"},
        {NULL, NULL, 0, NULL}
 };
 
-/**************** prototypes ********************/
-PyObject *Particle_Init( void );
-
-
 /*****************************************************************************/
-/* Python Particle_Type structure definition:                                */
+/* Python BPy_ParticleSys attributes get/set structure:                           */
 /*****************************************************************************/
-
-PyTypeObject Particle_Type = {
-       PyObject_HEAD_INIT( NULL )
-               0,
-       "Particle",
-       sizeof( BPy_Particle ),
-       0,
-
-       ( destructor ) ParticleDeAlloc,
-       0,
-       ( getattrfunc ) ParticleGetAttr,
-       ( setattrfunc ) ParticleSetAttr,
-       0,
-       ( reprfunc ) ParticleRepr,
-       0,
-       0,
-       0,
-       0,
-       0, 0, 0, 0, 0, 0,
-       0,
-       0, 0, 0, 0, 0, 0,
-       BPy_Particle_methods,
-       0,
+static PyGetSetDef BPy_ParticleSys_getseters[] = {
+/* Extras */
+       {"seed",
+        (getter)Part_getSeed, (setter)Part_setSeed,
+        "Set an offset in the random table",
+        NULL},
+ /* basics */
+       {"type",
+        (getter)Part_getType, (setter)Part_setType,
+        "Type of particle system ( Particle.TYPE[ 'HAIR' | 'REACTOR' | 'EMITTER' ] )",
+        NULL},
+       {"resolutionGrid",
+        (getter)Part_getResol, (setter)Part_setResol,
+        "The resolution of the particle grid",
+        NULL},
+       {"startFrame",
+        (getter)Part_getStart, (setter)Part_setStart,
+        "Frame # to start emitting particles",
+        NULL},
+       {"endFrame",
+        (getter)Part_getEnd, (setter)Part_setEnd,
+        "Frame # to stop emitting particles",
+        NULL},
+       {"editable",
+        (getter)Part_getEditable, (setter)Part_setEditable,
+        "Finalize hair to enable editing in particle mode",
+        NULL},
+    {"amount",
+        (getter)Part_getAmount, (setter)Part_setAmount,
+        "The total number of particles",
+        NULL},
+    {"multireact",
+        (getter)Part_getMultiReact, (setter)Part_setMultiReact,
+        "React multiple times ( Paricle.REACTON[ 'NEAR' | 'COLLISION' | 'DEATH' ] )",
+        NULL},
+    {"reactshape",
+        (getter)Part_getReactShape, (setter)Part_setReactShape,
+        "Power of reaction strength dependence on distance to target",
+        NULL},
+    {"hairSegments",
+        (getter)Part_getSegments, (setter)Part_setSegments,
+        "Amount of hair segments",
+        NULL},
+    {"lifetime",
+        (getter)Part_getLife, (setter)Part_setLife,
+        "Specify the life span of the particles",
+        NULL},
+    {"randlife",
+        (getter)Part_getRandLife, (setter)Part_setRandLife,
+        "Give the particle life a random variation",
+        NULL},
+     {"randemission",
+        (getter)Part_getRandEmission, (setter)Part_setRandEmission,
+        "Give the particle life a random variation",
+        NULL},
+     {"particleDistribution",
+        (getter)Part_getParticleDist, (setter)Part_setParticleDist,
+        "Where to emit particles from  Paricle.EMITFROM[ 'PARTICLE' | 'VOLUME' | 'FACES' | 'VERTS' ] )",
+        NULL},
+     {"evenDistribution",
+        (getter)Part_getEvenDist, (setter)Part_setEvenDist,
+        "Use even distribution from faces based on face areas or edge lengths",
+        NULL},
+     {"distribution",
+        (getter)Part_getDist, (setter)Part_setDist,
+        "How to distribute particles on selected element Paricle.DISTRIBUTION[ 'GRID' | 'RANDOM' | 'JITTERED' ] )",
+        NULL},
+     {"jitterAmount",
+        (getter)Part_getJitterAmount, (setter)Part_setJitterAmount,
+        "Amount of jitter applied to the sampling",
+        NULL},
+     {"pf",
+        (getter)Part_getPF, (setter)Part_setPF,
+        "Emission locations / face (0 = automatic)",
+        NULL},
+     {"invert",
+        (getter)Part_getInvert, (setter)Part_setInvert,
+        "Invert what is considered object and what is not.",
+        NULL},
+     {"targetObject",
+        (getter)Part_getTargetOb, (setter)Part_setTargetOb,
+        "The object that has the target particle system (empty if same object)",
+        NULL},
+     {"targetpsys",
+        (getter)Part_getTargetPsys, (setter)Part_setTargetPsys,
+        "The target particle system number in the object",
+        NULL},
+/* Physics */
+    {"2d",
+        (getter)Part_get2d, (setter)Part_set2d,
+        "Constrain boids to a surface",
+        NULL},
+    {"maxvel",
+        (getter)Part_getMaxVel, (setter)Part_setMaxVel,
+        "Maximum velocity",
+        NULL},
+    {"avvel",
+        (getter)Part_getAvVel, (setter)Part_setAvVel,
+        "The usual speed % of max velocity",
+        NULL},
+    {"latacc",
+        (getter)Part_getLatAcc, (setter)Part_setLatAcc,
+        "Lateral acceleration % of max velocity",
+        NULL},
+    {"tanacc",
+        (getter)Part_getMaxTan, (setter)Part_setMaxTan,
+        "Tangential acceleration % of max velocity",
+        NULL},
+    {"groundz",
+        (getter)Part_getGroundZ, (setter)Part_setGroundZ,
+        "Default Z value",
+        NULL},
+     {"object",
+        (getter)Part_getOb, (setter)Part_setOb,
+        "Constrain boids to object's surface",
+        NULL},
+/* Visualisation */
+     {"renderEmitter",
+        (getter)Part_getRenderObject, (setter)Part_setRenderObject,
+        "Render emitter object",
+        NULL},
+     {"displayPercentage",
+        (getter)Part_getParticleDisp, (setter)Part_setParticleDisp,
+        "Particle display percentage",
+        NULL},
+     {"hairDisplayStep",
+        (getter)Part_getStep, (setter)Part_setStep,
+        "How many steps paths are drawn with (power of 2)",
+        NULL},
+     {"hairRenderStep",
+        (getter)Part_getRenderStep, (setter)Part_setRenderStep,
+        "How many steps paths are rendered with (power of 2)",
+        NULL},
+     {"duplicateObject",
+        (getter)Part_getDupOb, NULL,
+        "Get the duplicate ob",
+        NULL},
+     {"drawAs",
+        (getter)Part_getDrawAs, NULL,
+        "Get draw type Particle.DRAWAS([ 'NONE' | 'OBJECT' | 'POINT' | ... ] )",
+        NULL},
+       {NULL,NULL,NULL,NULL,NULL}  /* Sentinel */
 };
-/*****************************************************************************/
-/* The following string definitions are used for documentation strings.      */
-/* In Python these will be written to the console when doing a               */
-/* Blender.Particle.__doc__                                                  */
-/*****************************************************************************/
-char M_Particle_doc[] = "The Blender Particle module\n\n\
-This module provides access to **Object Data** in Blender.\n\
-Functions :\n\
-       New(object mesh's name) : creates a new part object and adds it to the given mesh object \n\
-       Get(name) : retreives a particle  with the given name (mandatory)\n\
-       get(name) : same as Get.  Kept for compatibility reasons.\n";
-char M_Particle_New_doc[] = "New(name) : creates a new part object and adds it to the given mesh object\n";
-char M_Particle_Get_doc[] = "xxx";
-
 
 /*****************************************************************************/
 /* Python method structure definition for Blender.Particle module:           */
 /*****************************************************************************/
-struct PyMethodDef M_Particle_methods[] = {
-       {"New", ( PyCFunction ) M_Particle_New, METH_VARARGS, M_Particle_New_doc},
-       {"Get", M_Particle_Get, METH_VARARGS, M_Particle_Get_doc},
-       {"get", M_Particle_Get, METH_VARARGS, M_Particle_Get_doc},
+static struct PyMethodDef M_ParticleSys_methods[] = {
+       {"New", ( PyCFunction ) M_ParticleSys_New, METH_VARARGS, M_ParticleSys_New_doc},
+       {"Get", M_ParticleSys_Get, METH_VARARGS, M_ParticleSys_Get_doc},
        {NULL, NULL, 0, NULL}
 };
 
+/*****************************************************************************/
+/* Python ParticleSys_Type structure definition:                                  */
+/*****************************************************************************/
+PyTypeObject ParticleSys_Type = {
+       PyObject_HEAD_INIT( NULL )  /* required py macro */
+       0,                          /* ob_size */
+       /*  For printing, in format "<module>.<name>" */
+       "Blender ParticleSys",           /* char *tp_name; */
+       sizeof( BPy_PartSys ),       /* int tp_basicsize; */
+       0,                          /* tp_itemsize;  For allocation */
+
+       /* Methods to implement standard operations */
+
+       NULL,                                           /* destructor tp_dealloc; */
+       NULL,                       /* printfunc tp_print; */
+       NULL,                       /* getattrfunc tp_getattr; */
+       NULL,                       /* setattrfunc tp_setattr; */
+       NULL,                       /* cmpfunc tp_compare; */
+       ( reprfunc ) ParticleSys_repr,/* reprfunc tp_repr; */
+
+       /* Method suites for standard classes */
+
+       NULL,                       /* PyNumberMethods *tp_as_number; */
+       NULL,                       /* PySequenceMethods *tp_as_sequence; */
+       NULL,                       /* PyMappingMethods *tp_as_mapping; */
+
+       /* More standard operations (here for binary compatibility) */
+
+       NULL,                       /* hashfunc tp_hash; */
+       NULL,                       /* ternaryfunc tp_call; */
+       NULL,                       /* reprfunc tp_str; */
+       NULL,                       /* getattrofunc tp_getattro; */
+       NULL,                       /* setattrofunc tp_setattro; */
+
+       /* Functions to access object as input/output buffer */
+       NULL,                       /* PyBufferProcs *tp_as_buffer; */
+
+  /*** Flags to define presence of optional/expanded features ***/
+       Py_TPFLAGS_DEFAULT,         /* long tp_flags; */
+
+       NULL,                       /*  char *tp_doc;  Documentation string */
+  /*** Assigned meaning in release 2.0 ***/
+       /* call function for all accessible objects */
+       NULL,                       /* traverseproc tp_traverse; */
+
+       /* delete references to contained objects */
+       NULL,                       /* inquiry tp_clear; */
+
+  /***  Assigned meaning in release 2.1 ***/
+  /*** rich comparisons ***/
+       NULL,                       /* richcmpfunc tp_richcompare; */
+
+  /***  weak reference enabler ***/
+       0,                          /* long tp_weaklistoffset; */
+
+  /*** Added in release 2.2 ***/
+       /*   Iterators */
+       NULL,                       /* getiterfunc tp_iter; */
+       NULL,                       /* iternextfunc tp_iternext; */
+
+  /*** Attribute descriptor and subclassing stuff ***/
+       BPy_ParticleSys_methods,      /* struct PyMethodDef *tp_methods; */
+       NULL,                       /* struct PyMemberDef *tp_members; */
+       BPy_ParticleSys_getseters,  /* struct PyGetSetDef *tp_getset; */
+       NULL,                       /* struct _typeobject *tp_base; */
+       NULL,                       /* PyObject *tp_dict; */
+       NULL,                       /* descrgetfunc tp_descr_get; */
+       NULL,                       /* descrsetfunc tp_descr_set; */
+       0,                          /* long tp_dictoffset; */
+       NULL,                       /* initproc tp_init; */
+       NULL,                       /* allocfunc tp_alloc; */
+       NULL,                       /* newfunc tp_new; */
+       /*  Low-level free-memory routine */
+       NULL,                       /* freefunc tp_free;  */
+       /* For PyObject_IS_GC */
+       NULL,                       /* inquiry tp_is_gc;  */
+       NULL,                       /* PyObject *tp_bases; */
+       /* method resolution order */
+       NULL,                       /* PyObject *tp_mro;  */
+       NULL,                       /* PyObject *tp_cache; */
+       NULL,                       /* PyObject *tp_subclasses; */
+       NULL,                       /* PyObject *tp_weaklist; */
+       NULL
+};
 
 /*****************************************************************************/
-/* Function:              M_Particle_New                                     */
-/* Python equivalent:     Blender.Effect.Particle.New                        */
-/* Description :          Create a particle effect and add a link            */
-/*                        to the given mesh-type Object                      */
-/* Data  :                String  mesh object name                           */
-/* Return :               pyobject particle                                  */
+/* Function:    PARTICLESYS_repr                                             */
+/* Description: This is a callback function for the BPy_Effect type. It      */
+/*              builds a meaninful string to represent effcte objects.       */
 /*****************************************************************************/
-PyObject *M_Particle_New( PyObject * self, PyObject * args )
+
+static PyObject *ParticleSys_repr( void )
 {
-       printf("warning, static particles api removed\n");
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyString_FromString( "ParticleSys" );
 }
 
 /*****************************************************************************/
-/* Function:              M_Particle_Get                                     */
-/* Python equivalent:     Blender.Effect.Particle.Get                        */
+/* Function : P_sys_FromPyObject                                           */
 /*****************************************************************************/
-PyObject *M_Particle_Get( PyObject * self, PyObject * args )
+
+struct ParticleSystem *P_sys_FromPyObject( BPy_PartSys * py_obj )
 {
-       printf("warning, static particles api removed\n");
-       Py_INCREF( Py_None );
-       return Py_None;
+       BPy_PartSys *blen_obj;
+
+       blen_obj = ( BPy_PartSys * ) py_obj;
+       return ( blen_obj->psys );
 }
 
 /*****************************************************************************/
-/* Function:              Particle_Init                                      */
+/* Function : ParticleSysCreatePyObject                                            */
 /*****************************************************************************/
-PyObject *Particle_Init( void )
+PyObject *ParticleSys_CreatePyObject( ParticleSystem * psystem, Object *ob )
 {
-       PyObject *submodule;
+       BPy_PartSys *blen_object;
+
+       blen_object =
+               ( BPy_PartSys * ) PyObject_NEW( BPy_PartSys, &ParticleSys_Type );
+
+       if( blen_object )
+               blen_object->psys = (ParticleSystem *)psystem;
+
+       blen_object->object = ob;
+
+       return ( PyObject * ) blen_object;
+}
+
+
+PyObject *M_ParticleSys_New( PyObject * self, PyObject * args ){
+       ParticleSystem *psys = 0;
+       ParticleSystem *rpsys = 0;
+       ModifierData *md;
+       ParticleSystemModifierData *psmd;
+       Object *ob = NULL;
+       char *name = NULL;
+       ID *id;
+       int nr;
+
+       if( !PyArg_ParseTuple( args, "s", &name ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                       "expected string argument" );
+
+       for( ob = G.main->object.first; ob; ob = ob->id.next )
+               if( !strcmp( name, ob->id.name + 2 ) )
+                       break;
+
+       if( !ob )
+               return EXPP_ReturnPyObjError( PyExc_AttributeError, 
+                       "object does not exist" );
+
+       id = (ID *)psys_new_settings("PSys", G.main);
+
+       psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");
+       psys->pointcache = BKE_ptcache_add();
+       psys->flag |= PSYS_ENABLED;
+       BLI_addtail(&ob->particlesystem,psys);
+
+       md = modifier_new(eModifierType_ParticleSystem);
+       sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem));
+       psmd = (ParticleSystemModifierData*) md;
+       psmd->psys=psys;
+       BLI_addtail(&ob->modifiers, md);
+
+       psys->part=(ParticleSettings*)id;
+       psys->totpart=0;
+       psys->flag=PSYS_ENABLED|PSYS_CURRENT;
+       psys->cfra=bsystem_time(ob,(float)G.scene->r.cfra+1,0.0);
+       rpsys = psys;
+
+       /* check need for dupliobjects */
+
+       nr=0;
+       for(psys=ob->particlesystem.first; psys; psys=psys->next){
+               if(ELEM(psys->part->draw_as,PART_DRAW_OB,PART_DRAW_GR))
+                       nr++;
+       }
+       if(nr)
+               ob->transflag |= OB_DUPLIPARTS;
+       else
+               ob->transflag &= ~OB_DUPLIPARTS;
+
+       BIF_undo_push("Browse Particle System");
+
+       DAG_scene_sort(G.scene);
+       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+
+       return ParticleSys_CreatePyObject(rpsys,ob);
+}
+
+
+/* 
+
+Get( name ) returns named particle sys or list of all
+throws NameError if name not found
+
+*/
+
+PyObject *M_ParticleSys_Get( PyObject * self, PyObject * args ) 
+{
+       ParticleSettings *psys_iter;
+       char *name = NULL;
+#if 0
+
+       ParticleSystem *blparticlesys = 0;
+       Object *ob;
+
+       PyObject *partsyslist,*current;
+#endif
+       if( !PyArg_ParseTuple( args, "|s", &name ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                               "expected string argument" );
+
+       psys_iter = G.main->particle.first; /* initialize our iterator */
+
+       if( name ) {   /* find psys by name */
+
+               PyObject *wanted_obj = NULL;
        
-       if( PyType_Ready( &Particle_Type) < 0)
-               return NULL;
+               while( psys_iter && ! wanted_obj ){
+                       if( !strcmp( name, psys_iter->id.name + 2)){
+                               printf("** found %s\n", psys_iter->id.name+2);
+                               //wanted_obj = ParticleSys_CreatePyObject( psys_iter );
+                               break;
+                       }
+                       psys_iter = psys_iter->id.next;
+               }
+
+               if( !wanted_obj){  /* requested object not found */
+                       char error_msg[64];
+                       PyOS_snprintf( error_msg, sizeof( error_msg ),
+                                                  "Particle System '%s' not found", name);
+                       return EXPP_ReturnPyObjError( PyExc_NameError, error_msg );
+               }
+
+               return wanted_obj;
+
+       }else {  /* no arg - return a list of bpy objs all P. systems */
+
+               PyObject *pylist;
+               int index = 0;
+
+               pylist = PyList_New( BLI_countlist( &G.main->particle ));
+               printf("** list is %d long\n", PyList_Size( pylist));
+               if( ! pylist ){
+                       return EXPP_ReturnPyObjError( 
+                               PyExc_MemoryError,
+                               "could not create ParticleSystem list");
+               }
+               
+               while( psys_iter ){
+#if 0
+                       pyobj = ParticleSystem_CreatePyObject( psys_iter);
+                       if( !pyobj){
+                               Py_DECREF( pylist );
+                               return EXPP_ReturnPyObjError(
+                                       PyExc_MemoryError, 
+                                       "could not create ParticleSystem PyObject");
+                       }
+                       PyList_SET_ITEM( pylist, index, pyobj);
+#endif
+                       printf("name is %s\n", psys_iter->id.name+2);
+                       psys_iter = psys_iter->id.next;
+                       index++;
+               }
+
+               return pylist;
+                       
+       }
+                       
+               
+
+#if 0
+
+       for( ob = G.main->particlesystem.first; ob; ob = ob->id.next )
+               if( !strcmp( name, ob->id.name + 2 ) )
+                       break;
+
+       if( !ob )
+               return EXPP_ReturnPyObjError( PyExc_AttributeError, 
+                               "object does not exist" );
+
+       blparticlesys = ob->particlesystem.first;
        
-       submodule =
-               Py_InitModule3( "Blender.Particle", M_Particle_methods, M_Particle_doc );
-       return ( submodule );
+
+       partsyslist = PyList_New( 0 );
+
+       if (!blparticlesys)
+               return partsyslist;
+
+       current = ParticleSys_CreatePyObject( blparticlesys, ob );
+       PyList_Append(partsyslist,current);
+
+
+       while((blparticlesys = blparticlesys->next)){
+               current = ParticleSys_CreatePyObject( blparticlesys, ob );
+               PyList_Append(partsyslist,current);
+       }
+
+       return partsyslist;
+
+#endif
 }
 
+
 /*****************************************************************************/
-/* Python BPy_Particle methods:                                                */
+/* Function:              ParticleSys_Init                                   */
 /*****************************************************************************/
 
-PyObject *Particle_getSta( BPy_Particle * self )
+/* create the Blender.Particle.Type constant dict */
+
+static PyObject *Particle_TypeDict( void )
 {
+       PyObject *Types = PyConstant_New(  );
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->sta );
-}
+       if( Types ) {
+               BPy_constant *c = ( BPy_constant * ) Types;
 
+               PyConstant_Insert( c, "HAIR",
+                                PyInt_FromLong( 2 ) );
+               PyConstant_Insert( c, "REACTOR",
+                                PyInt_FromLong( 1 ) );
+               PyConstant_Insert( c, "EMITTER",
+                                PyInt_FromLong( 0 ) );
+       }
+       return Types;
+}
 
+/* create the Blender.Particle.Distribution constant dict */
 
-PyObject *Particle_setSta( BPy_Particle * self, PyObject * args )
+static PyObject *Particle_DistrDict( void )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->sta = val;
-       Py_INCREF( Py_None );
-       return Py_None;
-}
+       PyObject *Distr = PyConstant_New(  );
 
-PyObject *Particle_getEnd( BPy_Particle * self )
-{
+       if( Distr ) {
+               BPy_constant *c = ( BPy_constant * ) Distr;
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->end );
+               PyConstant_Insert( c, "GRID",
+                                PyInt_FromLong( 2 ) );
+               PyConstant_Insert( c, "RANDOM",
+                                PyInt_FromLong( 1 ) );
+               PyConstant_Insert( c, "JITTERED",
+                                PyInt_FromLong( 0 ) );
+       }
+       return Distr;
 }
 
+/* create the Blender.Particle.EmitFrom constant dict */
+
+static PyObject *Particle_EmitFrom( void )
+{
+       PyObject *EmitFrom = PyConstant_New(  );
+
+       if( EmitFrom ) {
+               BPy_constant *c = ( BPy_constant * ) EmitFrom;
+
+               PyConstant_Insert( c, "VERTS",
+                                PyInt_FromLong( 0 ) );
+               PyConstant_Insert( c, "FACES",
+                                PyInt_FromLong( 1 ) );
+               PyConstant_Insert( c, "VOLUME",
+                                PyInt_FromLong( 2 ) );
+               PyConstant_Insert( c, "PARTICLE",
+                                PyInt_FromLong( 3 ) );
+       }
+       return EmitFrom;
+}
 
+/* create the Blender.Particle.Collision constant dict */
 
-PyObject *Particle_setEnd( BPy_Particle * self, PyObject * args )
+static PyObject *Particle_ReactOnDict( void )
 {
-       float val = 0;
-       PartEff *ptr = ( PartEff * ) self->particle;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->end = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       PyObject *ReactOn = PyConstant_New(  );
+
+       if( ReactOn ) {
+               BPy_constant *c = ( BPy_constant * ) ReactOn;
+
+               PyConstant_Insert( c, "NEAR",
+                                PyInt_FromLong( 2 ) );
+               PyConstant_Insert( c, "COLLISION",
+                                PyInt_FromLong( 1 ) );
+               PyConstant_Insert( c, "DEATH",
+                                PyInt_FromLong( 0 ) );
+       }
+       return ReactOn;
 }
 
-PyObject *Particle_getLifetime( BPy_Particle * self )
+static PyObject *Particle_DrawAs( void )
 {
+       PyObject *DrawAs = PyConstant_New(  );
+
+       if( DrawAs ) {
+               BPy_constant *c = ( BPy_constant * ) DrawAs;
+
+               PyConstant_Insert( c, "NONE",
+                                PyInt_FromLong( 0 ) );
+               PyConstant_Insert( c, "POINT",
+                                PyInt_FromLong( 1 ) );
+               PyConstant_Insert( c, "CIRCLE",
+                                PyInt_FromLong( 2 ) );
+               PyConstant_Insert( c, "CROSS",
+                                PyInt_FromLong( 3 ) );
+               PyConstant_Insert( c, "AXIS",
+                                PyInt_FromLong( 4 ) );
+               PyConstant_Insert( c, "LINE",
+                                PyInt_FromLong( 5 ) );
+               PyConstant_Insert( c, "PATH",
+                                PyInt_FromLong( 6 ) );
+               PyConstant_Insert( c, "OBJECT",
+                                PyInt_FromLong( 7 ) );
+               PyConstant_Insert( c, "GROUP",
+                                PyInt_FromLong( 8 ) );
+               PyConstant_Insert( c, "BILLBOARD",
+                                PyInt_FromLong( 9 ) );
+       }
+       return DrawAs;
+}
+
+void Particle_Recalc(BPy_PartSys* self,int child){
+       psys_flush_settings(self->psys->part,0,child );
+}
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->lifetime );
+void Particle_RecalcPsys_distr(BPy_PartSys* self,int child){
+       psys_flush_settings(self->psys->part,PSYS_DISTR,child);
 }
 
+PyObject *ParticleSys_Init( void ){
+       PyObject *submodule;
+       PyObject *Types;
+       PyObject *React;
+       PyObject *EmitFrom;
+       PyObject *Dist;
+       PyObject *DrawAs;
 
+       if( PyType_Ready( &ParticleSys_Type ) < 0)
+               return NULL;
 
-PyObject *Particle_setLifetime( BPy_Particle * self, PyObject * args )
-{
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->lifetime = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       Types = Particle_TypeDict ();
+       React = Particle_ReactOnDict();
+       EmitFrom = Particle_EmitFrom();
+       DrawAs = Particle_DrawAs();
+       Dist = Particle_DistrDict();
+
+       submodule = Py_InitModule3( "Blender.Particle", 
+                                                               M_ParticleSys_methods, M_ParticleSys_doc );
+
+       if( Types )
+               PyModule_AddObject( submodule, "TYPE", Types );
+       if( React )
+               PyModule_AddObject( submodule, "REACTON", React );
+       if( EmitFrom )
+               PyModule_AddObject( submodule, "EMITFROM", EmitFrom );
+       if( Dist )
+               PyModule_AddObject( submodule, "DISTRIBUTION", Dist );
+       if( DrawAs )
+               PyModule_AddObject( submodule, "DRAWAS", DrawAs );
+
+       return ( submodule );
 }
 
+static PyObject *Part_freeEdit( BPy_PartSys * self, PyObject * args ){
 
-PyObject *Particle_getNormfac( BPy_Particle * self )
-{
+       if(self->psys->flag & PSYS_EDITED){
+               if(self->psys->edit)
+                       PE_free_particle_edit(self->psys);
+
+               self->psys->flag &= ~PSYS_EDITED;
+               self->psys->recalc |= PSYS_RECALC_HAIR;
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->normfac );
+               DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
+       }
+       Py_RETURN_NONE;
 }
 
+static PyObject *Part_GetLoc( BPy_PartSys * self, PyObject * args ){
+       ParticleSystem *psys = 0L;
+       Object *ob = 0L;
+       PyObject *partlist,*seglist;
+       PyObject* loc = 0L;
+       ParticleCacheKey **cache,*path;
+       ParticleKey state;
+       float cfra=bsystem_time(ob,(float)CFRA,0.0);
+       int i,j,k;
+       int     childexists = 0;
+       int all = 0;
+       int id = 0;
+
+       if( !PyArg_ParseTuple( args, "|ii", &all,&id ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                               "expected one optional integer as argument" );
+
+       psys = self->psys;
+       ob = self->object;
+       
+       if (!ob || !psys)
+               Py_RETURN_NONE;
+
+       if (psys->part->type == 2){
+               cache=psys->pathcache;
+
+               /* little hack to calculate hair steps in render mode */
+               psys->renderdata = (void*)(int)1;
+
+               psys_cache_paths(ob, psys, cfra, 0);
+
+               psys->renderdata = NULL;
+
+               partlist = PyList_New( 0 );
+               if( !partlist )
+                       return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
+
+               for(i = 0; i < psys->totpart; i++){
+                       path=cache[i];
+                       seglist = PyList_New( 0 );
+                       k = path->steps+1;
+                       for( j = 0; j < k ; j++){
+                               loc = PyTuple_New(3);
+
+                               PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)path->co[0]));
+                               PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)path->co[1]));
+                               PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)path->co[2]));
+
+                               if ( (PyList_Append(seglist,loc) < 0) ){
+                                       Py_DECREF(seglist);
+                                       Py_DECREF(partlist);
+                                       Py_XDECREF(loc);
+                                       return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                                       "Couldn't append item to PyList" );
+                               }
+
+                               path++;
+                       }
+
+                       if ( PyList_Append(partlist,seglist) < 0 ){
+                               Py_DECREF(seglist);
+                               Py_DECREF(partlist);
+                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                               "Couldn't append item to PyList" );             
+                       }
+               }
+
+               cache=psys->childcache;
+
+               for(i = 0; i < psys->totchild; i++){
+                       path=cache[i];
+                       seglist = PyList_New( 0 );
+                       k = path->steps+1;
+                       for( j = 0; j < k ; j++){
+                               loc = PyTuple_New(3);
+
+                               PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)path->co[0]));
+                               PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)path->co[1]));
+                               PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)path->co[2]));
+
+                               if ( PyList_Append(seglist,loc) < 0){
+                                       Py_DECREF(partlist);
+                                       Py_XDECREF(loc);
+                                       return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                                       "Couldn't append item to PyList" );
+                               }
+
+                               path++;
+                       }
+
+                       if ( PyList_Append(partlist,seglist) < 0){
+                               Py_DECREF(partlist);
+                               Py_XDECREF(loc);
+                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                               "Couldn't append item to PyList" );     
+                       }
+               }
+               
+       } else {
+               int init;
+               partlist = PyList_New( 0 );
+               if( !partlist )
+                       return EXPP_ReturnPyObjError( PyExc_MemoryError, "PyList() failed" );
+
+               if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
+                       childexists = 1;
+
+               for (i = 0; i < psys->totpart + psys->totchild; i++){
+                       if (childexists && (i < psys->totpart))
+                               continue;
+
+                       state.time = cfra;
+                       if(psys_get_particle_state(ob,psys,i,&state,0)==0)
+                               init = 0;
+                       else
+                               init = 1;
+
+                       if (init){
+                               if (!id)
+                                       loc = PyTuple_New(3);
+                               else
+                                       loc = PyTuple_New(4);
+                               PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)state.co[0]));
+                               PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)state.co[1]));
+                               PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)state.co[2]));
+                               if (id)
+                                       PyTuple_SetItem(loc,3,PyInt_FromLong(i));
+
+                               if ( PyList_Append(partlist,loc) < 0 ){
+                                       Py_DECREF(partlist);
+                                       Py_XDECREF(loc);
+                                       return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                                               "Couldn't append item to PyList" );
+                               }
+                       }
+                       else {
+                               if ( all ){
+                                       if ( PyList_Append(partlist,Py_None) < 0 ){
+                                               Py_DECREF(partlist);
+                                               return EXPP_ReturnPyObjError( PyExc_RuntimeError,
+                                                                       "Couldn't append item to PyList" );
+                                       }
+                               }
+                       }
+               }
+       }
+       return partlist;
+}
 
+static PyObject *Part_GetRot( BPy_PartSys * self, PyObject * args ){
+       ParticleSystem *psys = 0L;
+       Object *ob = 0L;
+       PyObject *partlist = 0L;
+       PyObject* loc = 0L;
+       ParticleKey state;
+       int i;
+       int childexists = 0;
+       int all = 0;
+       int id = 0;
+
+       float cfra=bsystem_time(ob,(float)CFRA,0.0);
+
+       if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                               "expected one optional integer as argument" );
+
+       psys = self->psys;
+       ob = self->object;
+       
+       if (!ob || !psys)
+               Py_RETURN_NONE;
+
+       if (psys->part->type != 2){
+               partlist = PyList_New( 0 );
+
+               if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
+                       childexists = 1;
+
+               for (i = 0; i < psys->totpart + psys->totchild; i++){
+                       if (childexists && (i < psys->totpart))
+                               continue;
+
+                       state.time = cfra;
+                       if(psys_get_particle_state(ob,psys,i,&state,0)==0){
+                               if ( all ){
+                                       PyList_Append(partlist,Py_None);
+                                       continue;
+                               } else {
+                                       continue;
+                               }
+                       }
+                       if (!id)
+                               loc = PyTuple_New(4);
+                       else
+                               loc = PyTuple_New(5);
+                       PyTuple_SetItem(loc,0,PyFloat_FromDouble((double)state.rot[0]));
+                       PyTuple_SetItem(loc,1,PyFloat_FromDouble((double)state.rot[1]));
+                       PyTuple_SetItem(loc,2,PyFloat_FromDouble((double)state.rot[2]));
+                       PyTuple_SetItem(loc,3,PyFloat_FromDouble((double)state.rot[3]));
+                       if (id)
+                               PyTuple_SetItem(loc,4,PyInt_FromLong(i));
+                       PyList_Append(partlist,loc);
+               }
+       }
+       return partlist;
+}
 
-PyObject *Particle_setNormfac( BPy_Particle * self, PyObject * args )
-{
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->normfac = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+static PyObject *Part_GetSize( BPy_PartSys * self, PyObject * args ){
+       ParticleKey state;
+       ParticleSystem *psys = 0L;
+       ParticleData *data;
+       Object *ob = 0L;
+       PyObject *partlist,*tuple;
+       PyObject* siz = 0L;
+       float size;
+       int i;
+       int childexists = 0;
+       int all = 0;
+       int id = 0;
+
+       float cfra=bsystem_time(ob,(float)CFRA,0.0);
+
+       if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                               "expected one optional integer as argument" );
+
+       data = self->psys->particles;
+
+       psys = self->psys;
+       ob = self->object;
+       
+       if (!ob || !psys)
+               Py_RETURN_NONE;
+
+               partlist = PyList_New( 0 );
+
+               if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
+                       childexists = 1;
+
+               for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
+               if (psys->part->type != 2){
+                       if (childexists && (i < psys->totpart))
+                               continue;
+
+                       if ( !all ){
+                               state.time = cfra;
+                               if(psys_get_particle_state(ob,psys,i,&state,0)==0)
+                                       continue;
+                       }
+
+                       if (i < psys->totpart){
+                               size = data->size;
+                       } else {
+                               ChildParticle *cpa= &psys->child[i-psys->totpart];
+                               size = psys_get_child_size(psys,cpa,cfra,0);
+                       }
+                       if (id){
+                               tuple = PyTuple_New(2);
+                               PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)size));
+                               PyTuple_SetItem(tuple,1,PyInt_FromLong(i));
+                               PyList_Append(partlist,tuple);
+                       } else {
+                               siz = PyFloat_FromDouble((double)size);
+                               PyList_Append(partlist,siz);
+                       }
+               }
+       }
+       return partlist;
 }
 
 
+static PyObject *Part_GetAge( BPy_PartSys * self, PyObject * args ){
+       ParticleKey state;
+       ParticleSystem *psys = 0L;
+       ParticleData *data;
+       Object *ob = 0L;
+       PyObject *partlist,*tuple;
+       PyObject* lif = 0L;
+       float life;
+       int i;
+       int childexists = 0;
+       int all = 0;
+       int id = 0;
 
-PyObject *Particle_getObfac( BPy_Particle * self )
-{
+       float cfra=bsystem_time(ob,(float)CFRA,0.0);
+
+       if( !PyArg_ParseTuple( args, "|ii", &all, &id ) )
+               return EXPP_ReturnPyObjError( PyExc_TypeError,
+                               "expected one optional integer as argument" );
+
+       data = self->psys->particles;
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->obfac );
+       psys = self->psys;
+       ob = self->object;
+       
+       if (!ob || !psys)
+               Py_RETURN_NONE;
+
+               partlist = PyList_New( 0 );
+
+               if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
+                       childexists = 1;
+
+               for (i = 0; i < psys->totpart + psys->totchild; i++, data++){
+               if (psys->part->type != 2){
+
+                       if (childexists && (i < psys->totpart))
+                               continue;
+
+                       if ( !all ){
+                               state.time = cfra;
+                               if(psys_get_particle_state(ob,psys,i,&state,0)==0)
+                                       continue;
+                       }
+
+                       if (i < psys->totpart){
+                               life = (cfra-data->time)/data->lifetime;
+                       } else {
+                               ChildParticle *cpa= &psys->child[i-psys->totpart];
+                               life = psys_get_child_time(psys,cpa,cfra);
+                       }
+                       if (id){
+                               tuple = PyTuple_New(2);
+                               PyTuple_SetItem(tuple,0,PyFloat_FromDouble((double)life));
+                               PyTuple_SetItem(tuple,1,PyInt_FromLong(i));
+                               PyList_Append(partlist,tuple);
+                       } else {
+                               lif = PyFloat_FromDouble((double)life);
+                               PyList_Append(partlist,lif);
+                       }
+               }
+       }
+       return partlist;
 }
 
 
+static PyObject *Part_GetMat( BPy_PartSys * self, PyObject * args ){
+       Material *ma;
+       PyObject* mat = 0L;
+       ma = give_current_material(self->object,self->psys->part->omat);
+       if(!ma)
+               Py_RETURN_NONE;
 
-PyObject *Particle_setObfac( BPy_Particle * self, PyObject * args )
-{
-       float val = 0;
-       PartEff *ptr = ( PartEff * ) self->particle;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->obfac = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       mat = Material_CreatePyObject(ma);
+       return mat;
 }
 
 
+/*****************************************************************************/
+/* Function:              Set/Get Seed                                       */
+/*****************************************************************************/
 
-PyObject *Particle_getRandfac( BPy_Particle * self )
+static int Part_setSeed( BPy_PartSys * self, PyObject * args )
 {
+       return EXPP_setIValueRange( args, &self->psys->seed,
+                       0, 255, 'i' );
+}
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->randfac );
+static PyObject *Part_getSeed( BPy_PartSys * self )
+{
+       return PyInt_FromLong( (long)( self->psys->seed ) );
 }
 
+static int Part_setType( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setIValueRange( args, &self->psys->part->type,
+                       0, 2, 'h' );
 
+       psys_flush_settings( self->psys->part, PSYS_TYPE, 1 );
+
+       return res;
+}
 
-PyObject *Particle_setRandfac( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getType( BPy_PartSys * self )
 {
-       float val = 0;
-       PartEff *ptr = ( PartEff * ) self->particle;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->randfac = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyInt_FromLong( (short)( self->psys->part->type ) );
 }
 
+static int Part_setResol( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setIValueRange( args, &self->psys->part->grid_res,
+                       0, 100, 'i' );
 
+       psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
 
-PyObject *Particle_getTexfac( BPy_Particle * self )
-{
+       return res;
+}
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->texfac );
+static PyObject *Part_getResol( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((int)( self->psys->part->grid_res )) );
 }
 
+static int Part_setStart( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->sta,
+                       0.0f, 100000.0f );
+
+       psys_flush_settings(self->psys->part,PSYS_INIT,1);
 
+       return res;
+}
 
-PyObject *Particle_setTexfac( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getStart( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->texfac = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyFloat_FromDouble( (float)( self->psys->part->sta ) );
 }
 
+static int Part_setEnd( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->end,
+                       0.0f, 100000.0f );
 
+       psys_flush_settings(self->psys->part,PSYS_INIT,1);
 
-PyObject *Particle_getRandlife( BPy_Particle * self )
-{
+       return res;
+}
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->randlife );
+static PyObject *Part_getEnd( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( (long)( self->psys->part->end ) );
 }
 
+static int Part_setEditable( BPy_PartSys * self, PyObject * args )
+{
+       int number;
+
+       if( !PyInt_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       number = PyInt_AS_LONG( args );
 
+       if(!number){
+               if(self->psys->edit)
+                       PE_free_particle_edit(self->psys);
 
-PyObject *Particle_setRandlife( BPy_Particle * self, PyObject * args )
+               self->psys->flag &= ~PSYS_EDITED;
+               self->psys->recalc |= PSYS_RECALC_HAIR;
+
+               DAG_object_flush_update(G.scene, self->object, OB_RECALC_DATA);
+       }
+       else
+       {
+               self->psys->flag |= PSYS_EDITED;
+               if(G.f & G_PARTICLEEDIT)
+                       PE_create_particle_edit(self->object, self->psys);
+       }
+
+       return 0;
+}
+
+static PyObject *Part_getEditable( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->randlife = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyInt_FromLong( ((long)( self->psys->flag & PSYS_EDITED )) > 0  );
 }
 
+static int Part_setAmount( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setIValueRange( args, &self->psys->part->totpart,
+                       0, 100000, 'i' );
 
+       psys_flush_settings( self->psys->part, PSYS_ALLOC, 1 );
 
-PyObject *Particle_getNabla( BPy_Particle * self )
-{
+       return res;
+}
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->nabla );
+static PyObject *Part_getAmount( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((int)( self->psys->part->totpart )) );
 }
 
+static int Part_setMultiReact( BPy_PartSys * self, PyObject * args )
+{
+       int number;
+
+       if( !PyInt_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       number = PyInt_AS_LONG( args );
+
+
+       if (number){
+               self->psys->part->flag |= PART_REACT_MULTIPLE;
+       }else{
+               self->psys->part->flag &= ~PART_REACT_MULTIPLE;
+       }
+
+       Particle_Recalc(self,1);
 
+       return 0;
+}
 
-PyObject *Particle_setNabla( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getMultiReact( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->nabla = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_REACT_MULTIPLE )) > 0 );
 }
 
+static int Part_setReactShape( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->reactshape,
+                       0.0f, 10.0f );
 
+       Particle_Recalc(self,1);
 
-PyObject *Particle_getVectsize( BPy_Particle * self )
-{
+       return res;
+}
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyFloat_FromDouble( ptr->vectsize );
+static PyObject *Part_getReactShape( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( ((double)( self->psys->part->reactshape )) );
 }
 
+static int Part_setSegments( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setIValueRange( args, &self->psys->part->hair_step,
+                       2, 50, 'h' );
 
+       Particle_Recalc(self,1);
 
-PyObject *Particle_setVectsize( BPy_Particle * self, PyObject * args )
-{
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val = 0;
-       if( !PyArg_ParseTuple( args, "f", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected float argument" ) );
-       ptr->vectsize = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return res;
 }
 
+static PyObject *Part_getSegments( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((long)( self->psys->part->hair_step )) );
+}
 
-PyObject *Particle_getTotpart( BPy_Particle * self )
+static int Part_setLife( BPy_PartSys * self, PyObject * args )
 {
+       int res = EXPP_setFloatRange( args, &self->psys->part->lifetime,
+                       1.0f, MAXFRAMEF );
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyInt_FromLong( ptr->totpart );
-}
+       Particle_Recalc(self,1);
 
+       return res;
+}
 
+static PyObject *Part_getLife( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( ((double)( self->psys->part->lifetime )) );
+}
 
-PyObject *Particle_setTotpart( BPy_Particle * self, PyObject * args )
+static int Part_setRandLife( BPy_PartSys * self, PyObject * args )
 {
-       int val = 0;
-       PartEff *ptr = ( PartEff * ) self->particle;
-       if( !PyArg_ParseTuple( args, "i", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected int argument" ) );
-       ptr->totpart = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       int res = EXPP_setFloatRange( args, &self->psys->part->randlife,
+                       0.0f, 2.0f );
+
+       Particle_Recalc(self,1);
+
+       return res;
 }
 
+static PyObject *Part_getRandLife( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( ((double)( self->psys->part->randlife )) );
+}
 
-PyObject *Particle_getTotkey( BPy_Particle * self )
+static int Part_set2d( BPy_PartSys * self, PyObject * args )
 {
+       int number;
+
+       if( !PyInt_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyInt_FromLong( ptr->totkey );
+       number = PyInt_AS_LONG( args );
+
+       if (number){
+               self->psys->part->flag |= PART_BOIDS_2D;
+       }else{
+               self->psys->part->flag &= ~PART_BOIDS_2D;
+       }
+
+       Particle_Recalc(self,1);
+
+       return 0;
 }
 
+static PyObject *Part_get2d( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 );
+}
+
+static int Part_setMaxVel( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->max_vel,
+                       0.0f, 200.0f );
+
+       Particle_Recalc(self,1);
 
+       return res;
+}
 
-PyObject *Particle_setTotkey( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getMaxVel( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       int val = 0;
-       if( !PyArg_ParseTuple( args, "i", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected int argument" ) );
-       ptr->totkey = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyFloat_FromDouble( ((double)( self->psys->part->max_vel )) );
 }
 
+static int Part_setAvVel( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->average_vel,
+                       0.0f, 1.0f );
+
+       Particle_Recalc(self,1);
+
+       return res;
+}
 
+static PyObject *Part_getAvVel( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( ((double)( self->psys->part->average_vel )) );
+}
 
-PyObject *Particle_getSeed( BPy_Particle * self )
+static int Part_setLatAcc( BPy_PartSys * self, PyObject * args )
 {
+       int res = EXPP_setFloatRange( args, &self->psys->part->max_lat_acc,
+                       0.0f, 1.0f );
+
+       Particle_Recalc(self,1);
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return PyInt_FromLong( ptr->seed );
+       return res;
 }
 
+static PyObject *Part_getLatAcc( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( ((double)( self->psys->part->max_lat_acc )) );
+}
 
+static int Part_setMaxTan( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->max_tan_acc,
+                       0.0f, 1.0f );
+
+       Particle_Recalc(self,1);
 
-PyObject *Particle_setSeed( BPy_Particle * self, PyObject * args )
+       return res;
+}
+
+static PyObject *Part_getMaxTan( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       int val = 0;
-       if( !PyArg_ParseTuple( args, "i", &val ) )
-               return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
-                                               "expected int argument" ) );
-       ptr->seed = val;
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyFloat_FromDouble( ((double)( self->psys->part->max_tan_acc )) );
 }
 
-PyObject *Particle_getForce( BPy_Particle * self )
+static int Part_setGroundZ( BPy_PartSys * self, PyObject * args )
 {
+       int res = EXPP_setFloatRange( args, &self->psys->part->groundz,
+                       -100.0f, 100.0f );
+
+       Particle_Recalc(self,1);
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return Py_BuildValue( "(f,f,f)", ptr->force[0], ptr->force[1],
-                             ptr->force[2] );
+       return res;
 }
 
+static PyObject *Part_getGroundZ( BPy_PartSys * self )
+{
+       return PyFloat_FromDouble( ((double)( self->psys->part->groundz )) );
+}
 
-PyObject *Particle_setForce( BPy_Particle * self, PyObject * args )
+static int Part_setOb( BPy_PartSys * self, PyObject * args )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val[3];
-       if( PyTuple_Size( args ) == 1 )
-               args = PyTuple_GetItem( args, 0 );
-       val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) );
-       val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) );
-       val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) );
-       /*
-          if (!PyArg_ParseTuple(args, "fff", val,val+1,val+2 ))
-          return(EXPP_ReturnPyObjError(PyExc_AttributeError,\
-          "expected three float arguments"));
-        */
-       ptr->force[0] = val[0];
-       ptr->force[1] = val[1];
-       ptr->force[2] = val[2];
-       Py_INCREF( Py_None );
-       return Py_None;
+       Object *obj;
+       if( !BPy_Object_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected object argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       obj = Object_FromPyObject(args);
+
+       self->psys->keyed_ob = obj;
+
+       return 0;
 }
 
-PyObject *Particle_getMult( BPy_Particle * self )
+static PyObject *Part_getOb( BPy_PartSys * self )
 {
+       Object * obj;
+       obj = self->psys->keyed_ob;
+       if (!obj)
+               Py_RETURN_NONE;
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return Py_BuildValue( "(f,f,f,f)",
-                             ptr->mult[0], ptr->mult[1], ptr->mult[2],
-                             ptr->mult[3] );
+       return Object_CreatePyObject( obj );
 }
 
+static int Part_setRandEmission( BPy_PartSys * self, PyObject * args )
+{
+       int number;
+
+       if( !PyInt_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       number = PyInt_AS_LONG( args );
+
+       if (number){
+               self->psys->part->flag |= PART_TRAND;
+       }else{
+               self->psys->part->flag &= ~PART_TRAND;
+       }
 
-PyObject *Particle_setMult( BPy_Particle * self, PyObject * args )
+       Particle_RecalcPsys_distr(self,1);
+
+       return 0;
+}
+
+static PyObject *Part_getRandEmission( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val[4];
-       if( PyTuple_Size( args ) == 1 )
-               args = PyTuple_GetItem( args, 0 );
-       val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) );
-       val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) );
-       val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) );
-       val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) );
-       ptr->mult[0] = val[0];
-       ptr->mult[1] = val[1];
-       ptr->mult[2] = val[2];
-       ptr->mult[3] = val[3];
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_BOIDS_2D )) > 0 );
 }
 
+static int Part_setParticleDist( BPy_PartSys * self, PyObject * args )
+{
+       int number;
+       char errstr[128];
 
+       if( !PyInt_Check( args ) ) {
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
 
+       number = PyInt_AS_LONG( args );
 
-PyObject *Particle_getLife( BPy_Particle * self )
-{
+       if (number < 0 || number > 3){
+               sprintf ( errstr, "expected int argument between 0 - 3" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return Py_BuildValue( "(f,f,f,f)",
-                             ptr->life[0], ptr->life[1], ptr->life[2],
-                             ptr->life[3] );
-}
+       self->psys->part->from = number;
+
+       Particle_RecalcPsys_distr(self,1);
 
+       return 0;
+}
 
-PyObject *Particle_setLife( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getParticleDist( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val[4];
-       if( PyTuple_Size( args ) == 1 )
-               args = PyTuple_GetItem( args, 0 );
-       val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) );
-       val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) );
-       val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) );
-       val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) );
-       ptr->life[0] = val[0];
-       ptr->life[1] = val[1];
-       ptr->life[2] = val[2];
-       ptr->life[3] = val[3];
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyInt_FromLong( (long)( self->psys->part->from ) );
 }
 
+static int Part_setEvenDist( BPy_PartSys * self, PyObject * args )
+{
+       int number;
+
+       if( !PyInt_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       number = PyInt_AS_LONG( args );
+
+       if (number){
+               self->psys->part->flag |= PART_EDISTR;
+       }else{
+               self->psys->part->flag &= ~PART_EDISTR;
+       }
+
+       Particle_RecalcPsys_distr(self,1);
+
+       return 0;
+}
 
+static PyObject *Part_getEvenDist( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_EDISTR )) > 0 );
+}
 
-PyObject *Particle_getChild( BPy_Particle * self )
+static int Part_setDist( BPy_PartSys * self, PyObject * args )
 {
+       int number;
+       char errstr[128];
+
+       if( !PyInt_Check( args ) ) {
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       number = PyInt_AS_LONG( args );
+
+       if (number < 0 || number > 2){
+               sprintf ( errstr, "expected int argument between 0 - 2" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       self->psys->part->distr = number;
+
+       Particle_RecalcPsys_distr(self,1);
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return Py_BuildValue( "(f,f,f,f)",
-                             ptr->child[0], ptr->child[1], ptr->child[2],
-                             ptr->child[3] );
+       return 0;
 }
 
+static PyObject *Part_getDist( BPy_PartSys * self )
+{
+       return PyInt_FromLong( (long)( self->psys->part->distr ) );
+}
+
+static int Part_setJitterAmount( BPy_PartSys * self, PyObject * args )
+{
+       int res = EXPP_setFloatRange( args, &self->psys->part->jitfac,
+                       0.0f, 2.0f );
+
+       Particle_RecalcPsys_distr(self,1);
+
+       return res;
+}
 
-PyObject *Particle_setChild( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getJitterAmount( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val[4];
-       if( PyTuple_Size( args ) == 1 )
-               args = PyTuple_GetItem( args, 0 );
-       val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) );
-       val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) );
-       val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) );
-       val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) );
-       ptr->child[0] = (short)val[0];
-       ptr->child[1] = (short)val[1];
-       ptr->child[2] = (short)val[2];
-       ptr->child[3] = (short)val[3];
-       Py_INCREF( Py_None );
-       return Py_None;
+       return PyFloat_FromDouble( ((double)( self->psys->part->jitfac )) );
 }
 
 
 
-PyObject *Particle_getMat( BPy_Particle * self )
+static int Part_setPF( BPy_PartSys * self, PyObject * args )
 {
+       int res = EXPP_setIValueRange( args, &self->psys->part->userjit,
+                       0, 1000, 'i' );
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return Py_BuildValue( "(f,f,f,f)",
-                             ptr->mat[0], ptr->mat[1], ptr->mat[2],
-                             ptr->mat[3] );
+       Particle_RecalcPsys_distr(self,1);
+
+       return res;
 }
 
+static PyObject *Part_getPF( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((short)( self->psys->part->userjit )) );
+}
 
-PyObject *Particle_setMat( BPy_Particle * self, PyObject * args )
+static int Part_setInvert( BPy_PartSys * self, PyObject * args )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val[4];
-       if( PyTuple_Size( args ) == 1 )
-               args = PyTuple_GetItem( args, 0 );
-       val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) );
-       val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) );
-       val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) );
-       val[3] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 3 ) );
-       ptr->mat[0] = (short)val[0];
-       ptr->mat[1] = (short)val[1];
-       ptr->mat[2] = (short)val[2];
-       ptr->mat[3] = (short)val[3];
-       Py_INCREF( Py_None );
-       return Py_None;
+       int number;
+
+       if( !PyInt_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected int argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
+
+       number = PyInt_AS_LONG( args );
+
+       if (number){
+               self->psys->part->flag |= PART_GRID_INVERT;
+       }else{
+               self->psys->part->flag &= ~PART_GRID_INVERT;
+       }
+
+       Particle_RecalcPsys_distr(self,1);
+
+       return 0;
 }
 
+static PyObject *Part_getInvert( BPy_PartSys * self )
+{
+       return PyInt_FromLong( ((long)( self->psys->part->flag & PART_GRID_INVERT )) > 0 );
+}
 
-PyObject *Particle_getDefvec( BPy_Particle * self )
+static int Part_setTargetOb( BPy_PartSys * self, PyObject * args )
 {
+       Object *obj;
+       if( !BPy_Object_Check( args ) ) {
+               char errstr[128];
+               sprintf ( errstr, "expected object argument" );
+               return EXPP_ReturnIntError( PyExc_TypeError, errstr );
+       }
 
-       PartEff *ptr = ( PartEff * ) self->particle;
-       return Py_BuildValue( "(f,f,f)",
-                             ptr->defvec[0], ptr->defvec[1], ptr->defvec[2] );
-}
+       obj = Object_FromPyObject(args);
 
+       self->psys->target_ob = obj;
+
+       return 0;
+}
 
-PyObject *Particle_setDefvec( BPy_Particle * self, PyObject * args )
+static PyObject *Part_getTargetOb( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self->particle;
-       float val[3];
-       if( PyTuple_Size( args ) == 1 )
-               args = PyTuple_GetItem( args, 0 );
-       val[0] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 0 ) );
-       val[1] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 1 ) );
-       val[2] = (float)PyFloat_AsDouble( PyTuple_GetItem( args, 2 ) );
-       ptr->defvec[0] = val[0];
-       ptr->defvec[1] = val[1];
-       ptr->defvec[2] = val[2];
-       Py_INCREF( Py_None );
-       return Py_None;
+       Object * obj;
+       obj = self->psys->target_ob;
+       if (!obj)
+               Py_RETURN_NONE;
+
+       return Object_CreatePyObject( obj );
 }
 
 
-/*****************************************************************************/
-/* Function:    ParticleDeAlloc                                              */
-/* Description: This is a callback function for the BPy_Particle type. It is   */
-/*              the destructor function.                                     */
-/*****************************************************************************/
-void ParticleDeAlloc( BPy_Particle * self )
+
+PyObject *Part_getDupOb( BPy_PartSys * self )
 {
-       PartEff *ptr = ( PartEff * ) self;
-       PyObject_DEL( ptr );
+       Object * obj;
+       obj = self->psys->part->dup_ob;
+       if (!obj)
+               Py_RETURN_NONE;
+
+       return Object_CreatePyObject( obj );
 }
 
-/*****************************************************************************/
-/* Function:    ParticleGetAttr                                              */
-/* Description: This is a callback function for the BPy_Particle type. It is */
-/*              the function that accesses BPy_Particle "member variables"   */
-/*      &