﻿<?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%3AIT%2F2.5%2FPy%2FScripts%2FCookbook%2FCode_snippets%2FMulti-File_packages</id>
	<title>Dev:IT/2.5/Py/Scripts/Cookbook/Code snippets/Multi-File packages - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3AIT%2F2.5%2FPy%2FScripts%2FCookbook%2FCode_snippets%2FMulti-File_packages"/>
	<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Multi-File_packages&amp;action=history"/>
	<updated>2026-08-02T06:54:20Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Multi-File_packages&amp;diff=105275&amp;oldid=prev</id>
		<title>Yamyam: 1版 をインポートしました</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Multi-File_packages&amp;diff=105275&amp;oldid=prev"/>
		<updated>2018-06-28T19:43:41Z</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日 (木) 19:43時点における版&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:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Multi-File_packages&amp;diff=105274&amp;oldid=prev</id>
		<title>2011年5月14日 (土) 20:47にwiki&gt;ValterVBによる</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Multi-File_packages&amp;diff=105274&amp;oldid=prev"/>
		<updated>2011-05-14T20:47:23Z</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;{{Page/Header|2.5x|Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Blender_add-ons|Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Simulations|100}}&lt;br /&gt;
&lt;br /&gt;
=Multi-file packages=&lt;br /&gt;
I {{Format/Literal|Packages}} sono un modo di strutturare lo spazio dei nomi dei moduli di Python usando nomi di modulo separati da punti. Per esempio, il nome del modulo &amp;lt;code&amp;gt;A.B&amp;lt;/code&amp;gt; designa un sottomodulo chiamato &amp;lt;code&amp;gt;B&amp;lt;/code&amp;gt; in un package chiamato &amp;lt;code&amp;gt;A&amp;lt;/code&amp;gt;. Proprio come l'uso dei moduli permette ad autori di moduli differenti di non doversi preoccupare dei nomi delle rispettive variabili globali, usare nomi di moduli separati da punti risparmia agli autori di package multi-modulari ogni preoccupazione circa i nomi dei moduli. Per ulteriori informazioni sui Python {{Format/Literal|packages}}, fai riferimento alla documentazione Python al seguente indirizzo [http://docs.python.org/tutorial/modules.html#packages Packages]&lt;br /&gt;
&lt;br /&gt;
Ogni package deve contenere un file chiamato &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt;. Questo file è richiesto per permettere a Python di trattare la directory come contenitore di package; questo è fatto per evitare che le directory con un nome comune, come stringa, nascondano involontariamente moduli validi che si verificano in seguito sul modulo di ricerca del percorso. Nel caso più semplice, &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; può essere semplicemente un file vuoto, ma può anche eseguire del codice di inizializzazione per il package. In Blender, &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; spesso contiene l'interfaccia utente e le informazioni sull'add-on, mentre il lavoro reale è fatto in altri file.&lt;br /&gt;
&lt;br /&gt;
Diversamente dagli altri script in questo libro, un multi-file package non può essere eseguito dal {{Format/Literal|text editor}}. Deve essere copiato in una directory che è inclusa nel percorso di ricerca di Blender, per es.  &amp;lt;code&amp;gt;addons&amp;lt;/code&amp;gt; o &amp;lt;code&amp;gt;addons-contrib&amp;lt;/code&amp;gt;, vedi la sezione [[Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Blender_add-ons|Blender add-ons]]. Fortunatamente non devi riavviare Blender per ricaricare i files dopo ogni modifica. Premi {{Shortcut|F8}} per ricaricare tutti gli add-ons in Blender.&lt;br /&gt;
&lt;br /&gt;
==Un semplice esempio==&lt;br /&gt;
Questo package è diviso in quattro file. Tre di questi creano delle mesh; rispettivamente un cubo, un cilindro, e una sfera. Questi file sono script indipendenti che possono essere eseguiti nella finestra {{Format/Literal|text editor}} per poter fare il debugging. La condizione &amp;lt;code&amp;gt;(__name__ == &amp;quot;__main__&amp;quot;)&amp;lt;/code&amp;gt; è vera quando il file è eseguito in modalità indipendente.&lt;br /&gt;
&lt;br /&gt;
===mycube.py===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File mycube.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
def makeMesh(z):&lt;br /&gt;
    bpy.ops.mesh.primitive_cube_add(location=(0,0,z))&lt;br /&gt;
    return bpy.context.object&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    ob = makeMesh(1)&lt;br /&gt;
    print(ob, &amp;quot;created&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===mycylinder.py===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File mycylinder.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
def makeMesh(z):&lt;br /&gt;
    bpy.ops.mesh.primitive_cylinder_add(location=(0,0,z))&lt;br /&gt;
    return bpy.context.object&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    ob = makeMesh(5)&lt;br /&gt;
    print(ob, &amp;quot;created&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===mysphere.py===&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File mysphere.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
def makeMesh(z):&lt;br /&gt;
    bpy.ops.mesh.primitive_ico_sphere_add(location=(0,0,z))&lt;br /&gt;
    return bpy.context.object&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    ob = makeMesh(3)&lt;br /&gt;
    print(ob, &amp;quot;created&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===__init__.py===&lt;br /&gt;
Il quarto file contiene il dizionario &amp;lt;code&amp;gt;bl_info&amp;lt;/code&amp;gt; e la registrazione necessaria per gli add-on e l'interfaccia utente. Contiene anche il seguente pezzo di codice per importare gli altri file nel package.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
# To support reload properly, try to access a package var, &lt;br /&gt;
# if it's there, reload everything&lt;br /&gt;
if &amp;quot;bpy&amp;quot; in locals():&lt;br /&gt;
    import imp&lt;br /&gt;
    imp.reload(mycube)&lt;br /&gt;
    imp.reload(mysphere)&lt;br /&gt;
    imp.reload(mycylinder)&lt;br /&gt;
    print(&amp;quot;Reloaded multifiles&amp;quot;)&lt;br /&gt;
else:&lt;br /&gt;
    from . import mycube, mysphere, mycylinder&lt;br /&gt;
    print(&amp;quot;Imported multifiles&amp;quot;)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Questo codice lavora nella seguente maniera.&lt;br /&gt;
* Se &amp;lt;code&amp;gt;__init__.py()&amp;lt;/code&amp;gt; è eseguito per la prima volta, per es. all'avvio di Blender con l'add-on abiilitato, &amp;lt;code&amp;gt;&amp;quot;bpy&amp;quot;&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;locals()&amp;lt;/code&amp;gt; è False.Gli altri file nel package sono importati, e  Imported multifiles è stampato nella console.&lt;br /&gt;
* Se &amp;lt;code&amp;gt;__init__.py()&amp;lt;/code&amp;gt; è eseguito per la prima volta dopo l'avvio di Blender, con l'add-on disabilitato, e clicchi su abilita add-on, &amp;lt;code&amp;gt;&amp;quot;bpy&amp;quot;&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;locals()&amp;lt;/code&amp;gt; è False. Gli altri file nel package sono importati, e Imported multifiles è stampato nella console.&lt;br /&gt;
* Una volta che l'add-on è abilitato, ogni volta che premi {{Shortcut|F8}} per ricaricare gli add-on, &amp;lt;code&amp;gt;&amp;quot;bpy&amp;quot;&amp;lt;/code&amp;gt; in &amp;lt;code&amp;gt;locals()&amp;lt;/code&amp;gt; è True. Gli altri file nel package sono ricaricati, e Reloaded multifiles è stampato nellam console.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File __init__.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
#    Addon info&lt;br /&gt;
bl_info = {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Multifile&amp;quot;,&lt;br /&gt;
    'author': 'Thomas Larsson',&lt;br /&gt;
    &amp;quot;location&amp;quot;: &amp;quot;View3D &amp;gt; UI panel &amp;gt; Add meshes&amp;quot;,&lt;br /&gt;
     &amp;quot;category&amp;quot;: &amp;quot;3D View&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
# To support reload properly, try to access a package var, &lt;br /&gt;
# if it's there, reload everything&lt;br /&gt;
if &amp;quot;bpy&amp;quot; in locals():&lt;br /&gt;
    import imp&lt;br /&gt;
    imp.reload(mycube)&lt;br /&gt;
    imp.reload(mysphere)&lt;br /&gt;
    imp.reload(mycylinder)&lt;br /&gt;
    print(&amp;quot;Reloaded multifiles&amp;quot;)&lt;br /&gt;
else:&lt;br /&gt;
    from . import mycube, mysphere, mycylinder&lt;br /&gt;
    print(&amp;quot;Imported multifiles&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
import bpy&lt;br /&gt;
from bpy.props import *&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#   class AddMeshPanel(bpy.types.Panel):&lt;br /&gt;
#&lt;br /&gt;
class AddMeshPanel(bpy.types.Panel):&lt;br /&gt;
    bl_label = &amp;quot;Add meshes&amp;quot;&lt;br /&gt;
    bl_space_type = &amp;quot;VIEW_3D&amp;quot;&lt;br /&gt;
    bl_region_type = &amp;quot;UI&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def draw(self, context):&lt;br /&gt;
        self.layout.operator(&amp;quot;multifile.add&amp;quot;, &lt;br /&gt;
            text=&amp;quot;Add cube&amp;quot;).mesh = &amp;quot;cube&amp;quot;&lt;br /&gt;
        self.layout.operator(&amp;quot;multifile.add&amp;quot;, &lt;br /&gt;
            text=&amp;quot;Add cylinder&amp;quot;).mesh = &amp;quot;cylinder&amp;quot;&lt;br /&gt;
        self.layout.operator(&amp;quot;multifile.add&amp;quot;, &lt;br /&gt;
            text=&amp;quot;Add sphere&amp;quot;).mesh = &amp;quot;sphere&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#   class OBJECT_OT_AddButton(bpy.types.Operator):&lt;br /&gt;
#&lt;br /&gt;
class OBJECT_OT_AddButton(bpy.types.Operator):&lt;br /&gt;
    bl_idname = &amp;quot;multifile.add&amp;quot;&lt;br /&gt;
    bl_label = &amp;quot;Add&amp;quot;&lt;br /&gt;
    mesh = bpy.props.StringProperty()&lt;br /&gt;
&lt;br /&gt;
    def execute(self, context):&lt;br /&gt;
        if self.mesh == &amp;quot;cube&amp;quot;:&lt;br /&gt;
            mycube.makeMesh(-8)&lt;br /&gt;
        elif self.mesh == &amp;quot;cylinder&amp;quot;:&lt;br /&gt;
            mycylinder.makeMesh(-5)&lt;br /&gt;
        elif self.mesh == &amp;quot;sphere&amp;quot;:&lt;br /&gt;
            mysphere.makeMesh(-2)&lt;br /&gt;
        return{'FINISHED'}    &lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#    Registration&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
def register():&lt;br /&gt;
    bpy.utils.register_module(__name__)&lt;br /&gt;
&lt;br /&gt;
def unregister():&lt;br /&gt;
    bpy.utils.unregister_module(__name__)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    register()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Un semplice importatore esportatore per obj==&lt;br /&gt;
Il formato obj è comunemente usato per scambiare i dati delle mesh tra differenti applicazioni. Originariamente inventato per Wavefront Maya, è diventato uno standard industriale. E' un semplice formato ASCII che contiene linee nel seguente formato:&lt;br /&gt;
* v ''x y z''&amp;lt;br&amp;gt;Coordinate del vertice, sono ''(x, y, z)''&lt;br /&gt;
* vt ''u v''&amp;lt;br&amp;gt;Coordinate del vertice della texture, sono ''(u, v)''&lt;br /&gt;
* f ''v&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; v&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; ... v&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;'' &amp;lt;br&amp;gt; Facce con ''n'' angoli, al vertice ''v&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, v&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, ... v&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;''. Per mesh senza UVs.&lt;br /&gt;
* f ''v&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;/vt&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt; v&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;/vt&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt; ... v&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;/vt&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;''&amp;lt;br&amp;gt;Facce con ''n'' angoli. Gli angoli sono al vertice ''v&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, v&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, ... v&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;'' nello spazio 3D e a ''vt&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;, vt&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;, ... vt&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;'' nello spazio della texture.&lt;br /&gt;
Esistono altri costrutti, per es. per le impostazioni del materiale e gruppi di facce, negli importatori/esportatori completi.&lt;br /&gt;
&lt;br /&gt;
Ci sono due cose da sapere. Primo, molte applicazioni (a quanto ne so, tutte eccetto Blender) usano la convenzione in cui l'asse dell Y punto in alto, mentre in Blender è l'asse delle Z che punta in alto. Secondo, Maya inizia a contare i vertici da 1, mentre Blender inizia a contare da 0. Questo significa che gli angoli delle facce sono realmente situate a ''v&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;-1, v&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;-1, ... v&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;-1'' nello spazio 3D e a ''vt&amp;lt;sub&amp;gt;1&amp;lt;/sub&amp;gt;-1, vt&amp;lt;sub&amp;gt;2&amp;lt;/sub&amp;gt;-1, ... vt&amp;lt;sub&amp;gt;n&amp;lt;/sub&amp;gt;-1'' nello spazio delle texture.&lt;br /&gt;
&lt;br /&gt;
Il semplice importatore-esportatore  di obj è un package Python composto da tre file: due file fanno il lavoro di import/export, e &amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; che trasforma la directory in un package.&lt;br /&gt;
&lt;br /&gt;
===Simple obj exporter===&lt;br /&gt;
Questo script esporta la mesh selezionata in un file obj.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File export_simple_obj.py&lt;br /&gt;
# Simple obj exporter which writes only verts, faces, and texture verts&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy, os&lt;br /&gt;
&lt;br /&gt;
def export_simple_obj(filepath, ob, rot90, scale):&lt;br /&gt;
    name = os.path.basename(filepath)&lt;br /&gt;
    realpath = os.path.realpath(os.path.expanduser(filepath))&lt;br /&gt;
    fp = open(realpath, 'w')    &lt;br /&gt;
    print('Exporting %s' % realpath)&lt;br /&gt;
&lt;br /&gt;
    if not ob or ob.type != 'MESH':&lt;br /&gt;
        raise NameError('Cannot export: active object %s is not a mesh.' % ob)&lt;br /&gt;
    me = ob.data&lt;br /&gt;
&lt;br /&gt;
    for v in me.vertices:&lt;br /&gt;
        x = scale*v.co&lt;br /&gt;
        if rot90:&lt;br /&gt;
            fp.write(&amp;quot;v %.5f %.5f %.5f\n&amp;quot; % (x[0], x[2], -x[1]))&lt;br /&gt;
        else:&lt;br /&gt;
            fp.write(&amp;quot;v %.5f %.5f %.5f\n&amp;quot; % (x[0], x[1], x[2]))&lt;br /&gt;
&lt;br /&gt;
    if len(me.uv_textures) &amp;gt; 0:&lt;br /&gt;
        uvtex = me.uv_textures[0]&lt;br /&gt;
        for f in me.faces:&lt;br /&gt;
            data = uvtex.data[f.index]&lt;br /&gt;
            fp.write(&amp;quot;vt %.5f %.5f\n&amp;quot; % (data.uv1[0], data.uv1[1]))&lt;br /&gt;
            fp.write(&amp;quot;vt %.5f %.5f\n&amp;quot; % (data.uv2[0], data.uv2[1]))&lt;br /&gt;
            fp.write(&amp;quot;vt %.5f %.5f\n&amp;quot; % (data.uv3[0], data.uv3[1]))&lt;br /&gt;
            if len(f.vertices) == 4:&lt;br /&gt;
                fp.write(&amp;quot;vt %.5f %.5f\n&amp;quot; % (data.uv4[0], data.uv4[1]))&lt;br /&gt;
&lt;br /&gt;
        vt = 1&lt;br /&gt;
        for f in me.faces:&lt;br /&gt;
            vs = f.vertices&lt;br /&gt;
            fp.write(&amp;quot;f %d/%d %d/%d %d/%d&amp;quot; % (vs[0]+1, vt, vs[1]+1, vt+1, vs[2]+1, vt+2))&lt;br /&gt;
            vt += 3&lt;br /&gt;
            if len(f.vertices) == 4:&lt;br /&gt;
                fp.write(&amp;quot; %d/%d\n&amp;quot; % (vs[3]+1, vt))&lt;br /&gt;
                vt += 1        &lt;br /&gt;
            else:&lt;br /&gt;
                fp.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
    else:&lt;br /&gt;
        for f in me.faces:&lt;br /&gt;
            vs = f.vertices&lt;br /&gt;
            fp.write(&amp;quot;f %d %d %d&amp;quot; % (vs[0]+1, vs[1]+1, vs[2]+1))&lt;br /&gt;
            if len(f.vertices) == 4:&lt;br /&gt;
                fp.write(&amp;quot; %d\n&amp;quot; % (vs[3]+1))&lt;br /&gt;
            else:&lt;br /&gt;
                fp.write(&amp;quot;\n&amp;quot;)&lt;br /&gt;
    &lt;br /&gt;
    print('%s successfully exported' % realpath)&lt;br /&gt;
    fp.close()&lt;br /&gt;
    return&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Simple obj import===&lt;br /&gt;
Questo script è il compagno di importazione di quello precedente. Si può naturalmente anche utilizzare per importare i file obj da altre applicazioni.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File import_simple_obj.py&lt;br /&gt;
# Simple obj importer which reads only verts, faces, and texture verts&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
import bpy, os&lt;br /&gt;
&lt;br /&gt;
def import_simple_obj(filepath, rot90, scale):&lt;br /&gt;
    name = os.path.basename(filepath)&lt;br /&gt;
    realpath = os.path.realpath(os.path.expanduser(filepath))&lt;br /&gt;
    fp = open(realpath, 'rU')    # Universal read&lt;br /&gt;
    print('Importing %s' % realpath)&lt;br /&gt;
&lt;br /&gt;
    verts = []&lt;br /&gt;
    faces = []&lt;br /&gt;
    texverts = []&lt;br /&gt;
    texfaces = []&lt;br /&gt;
&lt;br /&gt;
    for line in fp:&lt;br /&gt;
        words = line.split()&lt;br /&gt;
        if len(words) == 0:&lt;br /&gt;
            pass&lt;br /&gt;
        elif words[0] == 'v':&lt;br /&gt;
            (x,y,z) = (float(words[1]), float(words[2]), float(words[3]))&lt;br /&gt;
            if rot90:&lt;br /&gt;
                verts.append( (scale*x, -scale*z, scale*y) )&lt;br /&gt;
            else:&lt;br /&gt;
                verts.append( (scale*x, scale*y, scale*z) )&lt;br /&gt;
        elif words[0] == 'vt':&lt;br /&gt;
            texverts.append( (float(words[1]), float(words[2])) )&lt;br /&gt;
        elif words[0] == 'f':&lt;br /&gt;
            (f,tf) = parseFace(words)&lt;br /&gt;
            faces.append(f)&lt;br /&gt;
            if tf:&lt;br /&gt;
                texfaces.append(tf)&lt;br /&gt;
        else:&lt;br /&gt;
            pass&lt;br /&gt;
    print('%s successfully imported' % realpath)&lt;br /&gt;
    fp.close()&lt;br /&gt;
&lt;br /&gt;
    me = bpy.data.meshes.new(name)&lt;br /&gt;
    me.from_pydata(verts, [], faces)&lt;br /&gt;
    me.update()&lt;br /&gt;
&lt;br /&gt;
    if texverts:&lt;br /&gt;
        uvtex = me.uv_textures.new()&lt;br /&gt;
        uvtex.name = name&lt;br /&gt;
        data = uvtex.data&lt;br /&gt;
        for n in range(len(texfaces)):&lt;br /&gt;
            tf = texfaces[n]&lt;br /&gt;
            data[n].uv1 = texverts[tf[0]]&lt;br /&gt;
            data[n].uv2 = texverts[tf[1]]&lt;br /&gt;
            data[n].uv3 = texverts[tf[2]]&lt;br /&gt;
            if len(tf) == 4:&lt;br /&gt;
                data[n].uv4 = texverts[tf[3]]&lt;br /&gt;
&lt;br /&gt;
    scn = bpy.context.scene&lt;br /&gt;
    ob = bpy.data.objects.new(name, me)&lt;br /&gt;
    scn.objects.link(ob)&lt;br /&gt;
    scn.objects.active = ob&lt;br /&gt;
&lt;br /&gt;
    return&lt;br /&gt;
    &lt;br /&gt;
def parseFace(words):&lt;br /&gt;
    face = []&lt;br /&gt;
    texface = []&lt;br /&gt;
    for n in range(1, len(words)):&lt;br /&gt;
        li = words[n].split('/')&lt;br /&gt;
        face.append( int(li[0])-1 )&lt;br /&gt;
        try:&lt;br /&gt;
            texface.append( int(li[1])-1 )&lt;br /&gt;
        except:&lt;br /&gt;
            pass&lt;br /&gt;
    return (face, texface)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===__init__.py===&lt;br /&gt;
Questo file contiene l'interfaccia utente, ovvero le due classi che creano le voci di menu per l'esportatore e l'importatore. Il semplice esportatore è richiamto dal menù {{Menu|File|Export}}. Ci sono due opzioni: una scelta booleana per ruotare la mesh di 90 gradi (per scambiare l'asse Y con l'asse Z), e un fattore di scala. Il semplice importatore è richiamato dal menù {{Menu|File|Import}}. Ci sono due opzioni: una scelta booleana per ruotare la mesh di 90 gradi (per far puntare in alto l'asse Z) e un fattore di scala.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;__init__.py&amp;lt;/code&amp;gt; contiene anche il dizionario &amp;lt;code&amp;gt;bl_info&amp;lt;/code&amp;gt; che rende il package un add-on di Blender, il codice di registrazione, e il codice per importare/ricaricare gli altri due file.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
# File __init__.py&lt;br /&gt;
#----------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
#    Addon info&lt;br /&gt;
bl_info = {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;Simple OBJ format&amp;quot;,&lt;br /&gt;
    &amp;quot;author&amp;quot;: &amp;quot;Thomas Larsson&amp;quot;,&lt;br /&gt;
    &amp;quot;location&amp;quot;: &amp;quot;File &amp;gt; Import-Export&amp;quot;,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Simple Wavefront obj import/export. Does meshes and UV coordinates&amp;quot;,&lt;br /&gt;
    &amp;quot;category&amp;quot;: &amp;quot;Import-Export&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
# To support reload properly, try to access a package var, &lt;br /&gt;
# if it's there, reload everything&lt;br /&gt;
if &amp;quot;bpy&amp;quot; in locals():&lt;br /&gt;
    import imp&lt;br /&gt;
    if 'simple_obj_import' in locals():&lt;br /&gt;
        imp.reload(simple_obj_import)&lt;br /&gt;
    if 'simple_obj_export' in locals():&lt;br /&gt;
        imp.reload(simple_obj_export)&lt;br /&gt;
&lt;br /&gt;
import bpy&lt;br /&gt;
from bpy.props import *&lt;br /&gt;
from io_utils import ExportHelper, ImportHelper&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#    Import menu&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
class IMPORT_OT_simple_obj(bpy.types.Operator, ImportHelper):&lt;br /&gt;
    bl_idname = &amp;quot;io_import_scene.simple_obj&amp;quot;&lt;br /&gt;
    bl_description = 'Import from simple OBJ file format (.obj)'&lt;br /&gt;
    bl_label = &amp;quot;Import simple OBJ&amp;quot;&lt;br /&gt;
    bl_space_type = &amp;quot;PROPERTIES&amp;quot;&lt;br /&gt;
    bl_region_type = &amp;quot;WINDOW&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    filename_ext = &amp;quot;.obj&amp;quot;&lt;br /&gt;
    filter_glob = StringProperty(default=&amp;quot;*.obj;*.mtl&amp;quot;, options={'HIDDEN'})&lt;br /&gt;
&lt;br /&gt;
    filepath = bpy.props.StringProperty(&lt;br /&gt;
        name=&amp;quot;File Path&amp;quot;, &lt;br /&gt;
        description=&amp;quot;File path used for importing the simple OBJ file&amp;quot;, &lt;br /&gt;
        maxlen= 1024, default= &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    rot90 = bpy.props.BoolProperty(&lt;br /&gt;
        name = &amp;quot;Rotate 90 degrees&amp;quot;,&lt;br /&gt;
        description=&amp;quot;Rotate mesh to Z up&amp;quot;,&lt;br /&gt;
        default = True)&lt;br /&gt;
&lt;br /&gt;
    scale = bpy.props.FloatProperty(&lt;br /&gt;
        name = &amp;quot;Scale&amp;quot;, &lt;br /&gt;
        description=&amp;quot;Scale mesh&amp;quot;, &lt;br /&gt;
        default = 0.1, min = 0.001, max = 1000.0)&lt;br /&gt;
&lt;br /&gt;
    def execute(self, context):&lt;br /&gt;
        from . import simple_obj_import&lt;br /&gt;
        print(&amp;quot;Load&amp;quot;, self.properties.filepath)&lt;br /&gt;
        simple_obj_import.import_simple_obj(&lt;br /&gt;
            self.properties.filepath, &lt;br /&gt;
            self.rot90, &lt;br /&gt;
            self.scale)&lt;br /&gt;
        return {'FINISHED'}&lt;br /&gt;
&lt;br /&gt;
    def invoke(self, context, event):&lt;br /&gt;
        context.window_manager.fileselect_add(self)&lt;br /&gt;
        return {'RUNNING_MODAL'}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#    Export menu&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
class EXPORT_OT_simple_obj(bpy.types.Operator, ExportHelper):&lt;br /&gt;
    bl_idname = &amp;quot;io_export_scene.simple_obj&amp;quot;&lt;br /&gt;
    bl_description = 'Export from simple OBJ file format (.obj)'&lt;br /&gt;
    bl_label = &amp;quot;Export simple OBJ&amp;quot;&lt;br /&gt;
    bl_space_type = &amp;quot;PROPERTIES&amp;quot;&lt;br /&gt;
    bl_region_type = &amp;quot;WINDOW&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    # From ExportHelper. Filter filenames.&lt;br /&gt;
    filename_ext = &amp;quot;.obj&amp;quot;&lt;br /&gt;
    filter_glob = StringProperty(default=&amp;quot;*.obj&amp;quot;, options={'HIDDEN'})&lt;br /&gt;
&lt;br /&gt;
    filepath = bpy.props.StringProperty(&lt;br /&gt;
        name=&amp;quot;File Path&amp;quot;, &lt;br /&gt;
        description=&amp;quot;File path used for exporting the simple OBJ file&amp;quot;, &lt;br /&gt;
        maxlen= 1024, default= &amp;quot;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    rot90 = bpy.props.BoolProperty(&lt;br /&gt;
        name = &amp;quot;Rotate 90 degrees&amp;quot;,&lt;br /&gt;
        description=&amp;quot;Rotate mesh to Y up&amp;quot;,&lt;br /&gt;
        default = True)&lt;br /&gt;
&lt;br /&gt;
    scale = bpy.props.FloatProperty(&lt;br /&gt;
        name = &amp;quot;Scale&amp;quot;, &lt;br /&gt;
        description=&amp;quot;Scale mesh&amp;quot;, &lt;br /&gt;
        default = 0.1, min = 0.001, max = 1000.0)&lt;br /&gt;
&lt;br /&gt;
    def execute(self, context):&lt;br /&gt;
        print(&amp;quot;Load&amp;quot;, self.properties.filepath)&lt;br /&gt;
        from . import simple_obj_export&lt;br /&gt;
        simple_obj_export.export_simple_obj(&lt;br /&gt;
            self.properties.filepath, &lt;br /&gt;
            context.object, &lt;br /&gt;
            self.rot90, &lt;br /&gt;
            1.0/self.scale)&lt;br /&gt;
        return {'FINISHED'}&lt;br /&gt;
&lt;br /&gt;
    def invoke(self, context, event):&lt;br /&gt;
        context.window_manager.fileselect_add(self)&lt;br /&gt;
        return {'RUNNING_MODAL'}&lt;br /&gt;
&lt;br /&gt;
#&lt;br /&gt;
#    Registration&lt;br /&gt;
#&lt;br /&gt;
&lt;br /&gt;
def menu_func_import(self, context):&lt;br /&gt;
    self.layout.operator(IMPORT_OT_simple_obj.bl_idname, text=&amp;quot;Simple OBJ (.obj)...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def menu_func_export(self, context):&lt;br /&gt;
    self.layout.operator(EXPORT_OT_simple_obj.bl_idname, text=&amp;quot;Simple OBJ (.obj)...&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
def register():&lt;br /&gt;
    bpy.utils.register_module(__name__)&lt;br /&gt;
    bpy.types.INFO_MT_file_import.append(menu_func_import)&lt;br /&gt;
    bpy.types.INFO_MT_file_export.append(menu_func_export)&lt;br /&gt;
&lt;br /&gt;
def unregister():&lt;br /&gt;
    bpy.utils.unregister_module(__name__)&lt;br /&gt;
    bpy.types.INFO_MT_file_import.remove(menu_func_import)&lt;br /&gt;
    bpy.types.INFO_MT_file_export.remove(menu_func_export)&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    register()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
{{Page/Footer|Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Blender_add-ons|Dev:IT/2.5/Py/Scripts/Cookbook/Code_snippets/Simulations}}&lt;/div&gt;</summary>
		<author><name>wiki&gt;ValterVB</name></author>
		
	</entry>
</feed>