﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3A2.4%2FPy%2FScripts%2FGuidelines%2Fprevious_work</id>
	<title>Dev:2.4/Py/Scripts/Guidelines/previous work - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3A2.4%2FPy%2FScripts%2FGuidelines%2Fprevious_work"/>
	<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:2.4/Py/Scripts/Guidelines/previous_work&amp;action=history"/>
	<updated>2026-06-07T12:22:12Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:2.4/Py/Scripts/Guidelines/previous_work&amp;diff=50882&amp;oldid=prev</id>
		<title>Yamyam: 1版 をインポートしました</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:2.4/Py/Scripts/Guidelines/previous_work&amp;diff=50882&amp;oldid=prev"/>
		<updated>2018-06-28T17:49:22Z</updated>

		<summary type="html">&lt;p&gt;1版 をインポートしました&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ja&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← 古い版&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;2018年6月28日 (木) 17:49時点における版&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ja&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(相違点なし)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Yamyam</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:2.4/Py/Scripts/Guidelines/previous_work&amp;diff=50881&amp;oldid=prev</id>
		<title>2010年3月31日 (水) 22:39にwiki&gt;Mindronesによる</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:2.4/Py/Scripts/Guidelines/previous_work&amp;diff=50881&amp;oldid=prev"/>
		<updated>2010-03-31T22:39:36Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== General Script Functionality ==&lt;br /&gt;
{{version|2.41+}}&lt;br /&gt;
This section sets out functionality and standards for scripts to be included in Blender.&lt;br /&gt;
&lt;br /&gt;
=== Python Version ===&lt;br /&gt;
Scripts distributed with Blender should be compatible with Python 2.3.&lt;br /&gt;
&lt;br /&gt;
=== Script Context ===&lt;br /&gt;
Before a user executes a script they need to know what it is operating on.&lt;br /&gt;
&lt;br /&gt;
This may be set in the name of the script (in the menu), its tooltip or the scripts user interface.&lt;br /&gt;
&lt;br /&gt;
Contexts may include...&lt;br /&gt;
* '''Active Object''' (only ever 1 object)&lt;br /&gt;
: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;obj = Blender.Scene.GetCurrent().getActiveObject()&amp;lt;/source&amp;gt;&lt;br /&gt;
* '''Selection''' (Assumed to mean visible Selection of current scene)&lt;br /&gt;
: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;scn = Blender.Scene.GetCurrent()&amp;lt;br&amp;gt;objects = [ob for ob in scn.getChildren() if ob.sel if ob.Layers &amp;amp; scn.Layers]&amp;lt;/source&amp;gt;&lt;br /&gt;
: or...&lt;br /&gt;
: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;objects = Blender.Object.GetSelected()&amp;lt;/source&amp;gt;&lt;br /&gt;
* '''Scene''' All objects in the current scene&lt;br /&gt;
: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;objects = Blender.Scene.GetCurrent().getChildren()&amp;lt;/source&amp;gt;&lt;br /&gt;
* '''All Scenes''' (In unusual situations you may need to operate on all scenes)&lt;br /&gt;
: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;objects = Blender.Object.Get()&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The context also needs to be set as to the type of data that is used. So if a script just operates on meshes, this needs to be stated. If no type is defined then the user will assume that its operating on objects/data of all types.&lt;br /&gt;
&lt;br /&gt;
====Rationale====&lt;br /&gt;
The user needs to know what the script is modifying, especialy when the data that is affected may not be visible at the time the script runs.&lt;br /&gt;
&lt;br /&gt;
The worst case is a script modifys data in hidden layers or another scene, the user saves over the older file and then discovers later that the hidden data has been modified and needs to be made again.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New Objects ===&lt;br /&gt;
Scripts that create new objects by importing, generation or working from the current selection must set all new objects selected and other objects unselected.&lt;br /&gt;
&lt;br /&gt;
New objects must never conflict with or overwrite existing data. scripts that use object or data names need to work properly when objects with the same names already exist. (be wary of &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;NMesh.PutRaw&amp;lt;/source&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
New objects must be...&lt;br /&gt;
* selected, unselecting all previously selected objects in the current scene.&lt;br /&gt;
* unique and not interfere with the existing data&lt;br /&gt;
* created in a visible layer&lt;br /&gt;
&lt;br /&gt;
====Rationale====&lt;br /&gt;
This is ideal because the user knows that all resulting data from the script is selected and can deal with the new data straight away.&lt;br /&gt;
&lt;br /&gt;
e.g. Move to another layer, remove an unwanted import, link to an empty scene or switch to local view to better see the newly created data.&lt;br /&gt;
&lt;br /&gt;
It is also consistant with current duplicate functionality.&lt;br /&gt;
&lt;br /&gt;
=== Scenes Context ===&lt;br /&gt;
Scripts, exporters specifically, need to only deal with the current scene unless otherwise specified.&lt;br /&gt;
&lt;br /&gt;
The usual mistake is to use '''&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Object.Get()&amp;lt;/source&amp;gt;''' as a list of objects to export from.&lt;br /&gt;
&lt;br /&gt;
This will export all scenes on-top of each other and may take a long time as well as giving the user a bad result.&lt;br /&gt;
&lt;br /&gt;
Use '''&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Scene.GetCurrent().getChildren()&amp;lt;/source&amp;gt;''' instead, so that all objects are taken from the scene that the user is currently working on.&lt;br /&gt;
&lt;br /&gt;
=== Progress ===&lt;br /&gt;
For scripts that could take more then 1 second, the user needs to know that the script is processing data and when the script is finished. Use &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Window.WaitCursor(1/0)&amp;lt;/source&amp;gt; to let the user know when the script is finished.&lt;br /&gt;
&lt;br /&gt;
You can also use &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Window.DrawProgressBar(0.0, 'progressText')&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Errors ===&lt;br /&gt;
Scripts should not cause python to raise errors.&lt;br /&gt;
&lt;br /&gt;
Problems with the users data, should be detected and a useful error appear.&lt;br /&gt;
&lt;br /&gt;
Error messages also need to say if they stop the script from completeing or just a warning.&lt;br /&gt;
e.g.:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Draw.PupMenu('ERROR%t|Select a mesh as your active object. aborting.')&amp;lt;/source&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Draw.PupMenu('WARNING%t|No materials applied to some objects. continuing.')&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Exception Handling ====&lt;br /&gt;
Using try/except blocks to handle errors is a good Thing and should be encouraged.&lt;br /&gt;
&lt;br /&gt;
Good exception handling can be used to make sure a script does not leave the Blender data in a half-finished or damaged state or to simply do general cleanup.&lt;br /&gt;
&lt;br /&gt;
=== Documenting Scripts ===&lt;br /&gt;
Willian- Comment?&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
Don't use &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;exec&amp;lt;/source&amp;gt; on unknown data, ask before overwriting? - expand&lt;br /&gt;
&lt;br /&gt;
== Import/Export API ==&lt;br /&gt;
Blender has a growing list of importers and exporters. Standardized function names allows us to use these scripts in a generic way.&lt;br /&gt;
&lt;br /&gt;
The most obvious use for this is as a file format converter, Blender supports these formats:&lt;br /&gt;
* 3DS&lt;br /&gt;
* OpenFlight FLT&lt;br /&gt;
* dxf&lt;br /&gt;
* obj&lt;br /&gt;
* Softaimage XSI&lt;br /&gt;
&lt;br /&gt;
With standards, we can have importers/exporters act in a predictable way for the user as well as making them automated from other python scripts.&lt;br /&gt;
&lt;br /&gt;
Here is an initial draft for a importer exporter API as well as some examples.&lt;br /&gt;
&lt;br /&gt;
=== File Naming ===&lt;br /&gt;
Files should start with either &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;import&amp;lt;/source&amp;gt; or &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;export&amp;lt;/source&amp;gt; then prefixed with the format they work with e.g.:&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;import_xsi.py&amp;lt;/source&amp;gt; &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;import_obj.py&amp;lt;/source&amp;gt;, &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;export_3ds.py&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== loading and saving function names ===&lt;br /&gt;
To be used by external scripts, the script's own user interface, or the file selector. These scripts cannot contain any user interaction.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;True&amp;lt;/source&amp;gt; or &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;False&amp;lt;/source&amp;gt; are returned based on weather the operation was successfull.&lt;br /&gt;
&lt;br /&gt;
These functions take 1 absolute path to a file and any number of optional keywords: '''&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;read(file, *keywords*)&amp;lt;/source&amp;gt;''' or '''&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;write(file, *keywords*)&amp;lt;/source&amp;gt;'''&lt;br /&gt;
&lt;br /&gt;
e.g. &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;write(file, EXPORT_EDGES=False, EXPORT_NORMALS=False, EXPORT_MTL=True, EXPORT_COPY_IMAGES=False, EXPORT_APPLY_MODIFIERS=True):&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== User interface (read_ui/write_ui) ===&lt;br /&gt;
This function handles all the user interation, and gathers the optional arguments to pass to read/write. UI Drawing, Calls to the FileSelector are set here.&lt;br /&gt;
&lt;br /&gt;
This function should never be called from anywhere other then the script itself.&lt;br /&gt;
&lt;br /&gt;
In most cases, &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Window.Fileselector&amp;lt;/source&amp;gt; will call this function and all it will take is the filename.&lt;br /&gt;
&lt;br /&gt;
=== Optional keywords ===&lt;br /&gt;
These optional keyword arguments can be passed to read and write functions.  Keywords are specific to that function and are used to set options as with the example above.  The keywords all need to have a default set so that the functions are optional, and scripts act as expected without having to pass specific keywords. - In most cases scripts that call the importers and exporters will not set non-default parameters.  However, this may be desirable under some conditions.&lt;br /&gt;
&lt;br /&gt;
Options keywords may be...&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;IMPORT_AT_CURSOR&amp;lt;/source&amp;gt; - Imports objects using the 3d cursor loaction for the 0/0/0 center.&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;IMPORT_INTO_NEW_SCENE&amp;lt;/source&amp;gt; - Creates a scene for the imported data.&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;IMPORT_MATERIAL&amp;lt;/source&amp;gt; - Creates materials for the imported file.&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;IMPORT_MESH_FGONS&amp;lt;/source&amp;gt; - Imports faces with more then 4 verts as fgons.&lt;br /&gt;
...and for exporters...&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;EXPORT_SCENE&amp;lt;/source&amp;gt; - Exports all objects in the scene, not just the selected, visible ones.&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;EXPORT_COPY_IMAGES&amp;lt;/source&amp;gt; - Copys all images to the output dir of the exported file.&lt;br /&gt;
* &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;EXPORT_SCALE&amp;lt;/source&amp;gt; - Scales the exported data by this factor.&lt;br /&gt;
&lt;br /&gt;
=== File compatibility testing function, importer only (iscompat) ===&lt;br /&gt;
This function takes a pathname and returns &amp;lt;code&amp;gt;True/False&amp;lt;/code&amp;gt; depending on whether the file at the given path can be imported, this can be used to see if an importer can import a given file. For basic testing the file suffix is enough.&lt;br /&gt;
&lt;br /&gt;
e.g.: &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;return file.lower.endswith('.obj')&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data Compatibility Constant ===&lt;br /&gt;
Every i/o scipt must have a variable called '''&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;__FORMAT_COMPATIBILITY__'''&amp;lt;/source&amp;gt;, this is a list of standard names that define what kinds of data the script can read/write.&lt;br /&gt;
&lt;br /&gt;
e.g. &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;__FORMAT_COMPATIBILITY__ = 'MESH', 'MESH_NAME', 'MESH_VERT', 'MESH_EDGE', 'MESH_FACE', 'MESH_MATERIAL', 'MATERIAL', 'MESH_TEXFACE'&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The rationale for having this variable is that an external script can load an importer &amp;amp; exporter, telling the user what data will be lost if a conversion is made.&lt;br /&gt;
&lt;br /&gt;
As scripts are converted the list of names for supported data will be added to. since there is a lot of data that blender does not import/export to, once defined here, scripts will be expected to use these names.&lt;br /&gt;
&lt;br /&gt;
=== Blender Context ===&lt;br /&gt;
At the time of writing, importers and exporters have no defined context.  A context standard is needed so read and write can be called one after the other, converting the data, without losing objects in a hidden layer or through it being unselected.&lt;br /&gt;
&lt;br /&gt;
Currently some scripts export only the active object &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;(Blender.Object.GetSelection()[0])&amp;lt;/source&amp;gt;  Other scripts export objects from all scenes at once - &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.Object.Get()&amp;lt;/source&amp;gt; - Some scripts silently import over other meshes with existing names. &amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;Blender.NMesh.PutRaw()&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new standard will be to import and export the user selection. - That is...&lt;br /&gt;
* Importing replaces the selection in the current scene with a new set of selected objects in the visible layers.&lt;br /&gt;
* Exporting uses the current scenes visible selection as the data to export.&lt;br /&gt;
...In situations where a different context is required, an optional argument can be used to change the default context.&lt;br /&gt;
&lt;br /&gt;
=== Code Layout ===&lt;br /&gt;
All importers and exporters must follow this structure, foobar is used inplace of a real format name.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!BPY&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
Name: 'FooBar Model (.fbr)...'&lt;br /&gt;
Blender: 232&lt;br /&gt;
Group: 'Import'&lt;br /&gt;
Tooltip: 'Import a foobar file.'&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
__bpydoc__ = &amp;quot;&amp;quot;&amp;quot;\&lt;br /&gt;
Breif format description and any special notes.&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__FORMAT_COMPATIBILITY__ = 'MESH', 'MESH_VERT', 'MESH_FACE', 'MESH_MATERIAL'&lt;br /&gt;
&lt;br /&gt;
import Blender # Imports are optional, import whatever needs importing here.&lt;br /&gt;
&lt;br /&gt;
def iscompat(file): # Only for importers&lt;br /&gt;
  return file.lower().endswith('.fbr')&lt;br /&gt;
&lt;br /&gt;
def read(file, IMPORT_AT_CURSOR=False, IMPORT_SCALE=1.0, IMPORT_INTO_NEW_SCENE=False):&lt;br /&gt;
   # open and import the file&lt;br /&gt;
   return True # Import was a success&lt;br /&gt;
# This function can work however you like&lt;br /&gt;
# and should only be used by the script its self.&lt;br /&gt;
def read_ui(file): &lt;br /&gt;
  # Gather user option via PupMenu's, PupInput's, PupBlocks&lt;br /&gt;
  # or a Registered python user interface.&lt;br /&gt;
  &lt;br /&gt;
  # User interface aborts and tells&lt;br /&gt;
  # the user if the file isnt the right format.&lt;br /&gt;
  if not iscompat(file): ...&lt;br /&gt;
&lt;br /&gt;
  # Importing can take some time,&lt;br /&gt;
  #best give some visual feedback.&lt;br /&gt;
  Blender.Window.WaitCursor(1) &lt;br /&gt;
  time1 = Blender.sys.time()&lt;br /&gt;
  &lt;br /&gt;
  # We know the file exists and is compatible, import it.&lt;br /&gt;
  read(file, IMPORT_SOME_OPTION=True...) &lt;br /&gt;
&lt;br /&gt;
  Blender.Window.WaitCursor(0)&lt;br /&gt;
  # Usefull for the user to know the time an operation takes.&lt;br /&gt;
  print 'Foobar exported in %.4f sec.' % ( Blender.sys.time()-time1 ) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# This &amp;quot;if&amp;quot; is used so that importing the&lt;br /&gt;
# module dosent run the import user interface.&lt;br /&gt;
if __name__ == '__main__': &lt;br /&gt;
  Blender.Window.FileSelector(read_ui, 'Import FooBar', Blender.sys.makename(ext=&amp;quot;.fbr&amp;quot;)) &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Accessing read/write from other scripts ===&lt;br /&gt;
One of the main goals is to make the importers and exporters accessable as modules. Here is an example if a script that imports and exports a file.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import import_xsi&lt;br /&gt;
import export_3ds&lt;br /&gt;
file= 'C:\\temp\\testfile.xsi'&lt;br /&gt;
outfile= 'C:\\temp\\testfile.3ds'&lt;br /&gt;
if import_xsi.iscompat(file):&lt;br /&gt;
  retval= import_xsi.read(file)&lt;br /&gt;
  if retval:&lt;br /&gt;
    export_3ds.write(outfile)&lt;br /&gt;
  else:&lt;br /&gt;
    print 'File not written, error occured'&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Script]]&lt;/div&gt;</summary>
		<author><name>wiki&gt;Mindrones</name></author>
		
	</entry>
</feed>