Difference between revisions of "Scripting Guide"

From TexGen
Jump to navigationJump to search
Line 7: Line 7:
 
* [http://diveintopython.org/ Dive Into Python] - In depth book covering advanced subjects in a comprehensive manner. [http://diveintopython.org/toc/index.html HTML Version]
 
* [http://diveintopython.org/ Dive Into Python] - In depth book covering advanced subjects in a comprehensive manner. [http://diveintopython.org/toc/index.html HTML Version]
  
An advanced knowledge of Python is not needed in order to write simple TexGen scripts. However, bear in mind that Python is a very powerful language with many libraries included for performing common tasks. I suggest you try to follow through the examples below and if you get stuck refer to one of the documents above.
+
An advanced knowledge of Python is not needed in order to write simple TexGen scripts. However, bear in mind that Python is a very powerful language with many libraries included for performing common tasks.
  
===Example 1: A plain weave===
+
A series of tutorials on getting started with using Python in conjunction with TexGen are provided below. They have been written in such a way that they are best read sequentially since each one follows on from the previous:
First of all, a Python script is just a plain ASCII text file with a .py extension. To create one simply open up your favorite text editor. Notepad will do if you have nothing else but I suggest a more powerful freeware text editor like [http://www.pspad.com/ PSPad] or [http://notepad-plus.sourceforge.net/ Notepad++]. Code that goes into the python script will be displayed like so:
 
  
# All Python code will be shown in a box like this one.
+
* [[Scripting Create Models]]
# Lines begining with a '#' character are comments
+
* [[Scripting Export Mesh]]
 
 
In this example, we will create a simple 2x2 plain weave model with a Python script. Its time to dive in and see some actual Python code. At this point if you are completely lost please refer back to the resources on Python programming. The first step is to create an instance of the <code>CTextileWeave2D</code> class and give it a name, <code>weave</code>:
 
 
 
# Create a 2D weave textile
 
weave = CTextileWeave2D(2, 2, 1, 0.2, True)
 
 
 
The <code>CTextileWeave2D</code> class takes 5 parameters in the order shown below:
 
* Number of weft yarns in the unit cell
 
* Number of warp yarns in the unit cell
 
* Spacing between the yarns
 
* Thickness of the fabrics
 
* Refine model (True/False)
 
 
 
The only parameter that really needs an explanation here is the Refine model option, this controls whether or not the interference correction algorithm will be applied to keep the yarn volumes from intersecting which is a common problem. The interference correction algorithm generally does a good job but is not instantaneous so sometimes it can be beneficial to switch it off.
 
 
 
This is the bare minimum information necessary to create a 2D woven fabric. In the following steps we will add more information to create the model the way we want it.
 
 
 
Let's set the weave pattern, this determines whether a warp or weft yarn will appear on top at a particular cross over. Cross overs are arranged in 2d grid where the size of the grid depends on the number of warp and weft yarns created. To swap the positions of the weft and warp yarns, we call the function <code>SwapPosition</code> with the grid coordinates of the cross over. In order to create a plain weave we need to do this on two diagonally opposite cross overs like so:
 
 
 
# Set the weave pattern
 
weave.SwapPosition(0, 0)
 
weave.SwapPosition(1, 1)
 
 
 
Now let's add our <code>weave</code> model to the database of models so that TexGen can render it:
 
 
 
# Add the textile
 
AddTextile(weave)
 
 
 
Thats it! This is a very simple script but it will generate a plain weave model. To recap your Python script should look like this:
 
 
 
# Create a 2D weave textile
 
weave = CTextileWeave2D(2, 2, 1, 0.2, True)
 
 
# Set the weave pattern
 
weave.SwapPosition(0, 0)
 
weave.SwapPosition(1, 1)
 
 
# Add the textile
 
AddTextile(weave)
 
 
 
Save it to disk as ''PlainWeave.py'' or give it whatever name you want as long as it has a ''.py'' extension.
 
 
 
In order to test the Script we need to load it into TexGen. So start up the TexGen GUI and from the ''Python menu'' select ''Run Script''. Select the file you have just saved and click ok. With a bit of luck you should see a 2d plain weave on screen:
 
 
 
[[Image:Example1.png]]
 
 
 
Congratulations you have created your first TexGen Python script!
 
 
 
===Example 2: Another plain weave (the hard way)===
 
In the first example we made use of the <code>CTextileWeave2D</code> which is the reason the script is so compact. This was great for creating a 2D Weave, but what if we want to create something other than a 2D Weave? Well, let's stick to the 2D weave for now but in this example we will create geometric model in a generic way without the use of the <code>CTextileWeave2D</code> class. This takes a little bit longer to do, but gives more control over the final geometry.
 
 
 
First we will define a general textile and call it <code>Textile</code>:
 
 
 
# Create a textile
 
Textile = CTextile()
 
 
 
The <code>CTextile</code> class doesn't take any parameters, instead yarns will be created and added to it. Next we will create 4 yarns to go inside our textile, it is convenient to make use of the Python lists to do this. Create a list called <code>Yarns</code> with 4 elements, each one an instance of the class <code>CYarn</code>:
 
 
 
# Create a python list containing 4 yarns
 
Yarns = [CYarn(), CYarn(), CYarn(), CYarn()]
 
 
 
<code>Yarns</code> now contains 4 empty yarns. Note that the yarns are not currently associated with the Textile, first we must fill in the details then make them a part of the textile. The first thing to do is define their paths with nodes. This is done like so:
 
 
 
# Add nodes to the yarns to describe their paths
 
Yarns[0].AddNode(CNode(XYZ(0, 0, 0)))
 
Yarns[0].AddNode(CNode(XYZ(0.22, 0, 0.05)))
 
Yarns[0].AddNode(CNode(XYZ(0.44, 0, 0)))
 
 
Yarns[1].AddNode(CNode(XYZ(0, 0.22, 0.05)))
 
Yarns[1].AddNode(CNode(XYZ(0.22, 0.22, 0)))
 
Yarns[1].AddNode(CNode(XYZ(0.44, 0.22, 0.05)))
 
 
Yarns[2].AddNode(CNode(XYZ(0, 0, 0.05)))
 
Yarns[2].AddNode(CNode(XYZ(0, 0.22, 0)))
 
Yarns[2].AddNode(CNode(XYZ(0, 0.44, 0.05)))
 
 
Yarns[3].AddNode(CNode(XYZ(0.22, 0, 0)))
 
Yarns[3].AddNode(CNode(XYZ(0.22, 0.22, 0.05)))
 
Yarns[3].AddNode(CNode(XYZ(0.22, 0.44, 0)))
 
 
 
We have added 3 nodes to each yarn creating a woven pattern. The number in the square brackets after <code>Yarns</code> refers to a particular yarn in the list. The function <code>AddNode</code> is then called for the yarn. The function takes an instance of the class <code>CNode</code> which in turn is constructed with an instance of the class <code>XYZ</code> representing the position of the node. The class <code>XYZ</code> is constructed with 3 numbers representing the X, Y and Z coordinates of the point.
 
 
 
We still need to define a few more things to obtain a model. For the sake of simplicity, we will give all the yarns the same cross sectional shape, width, height, etc... The easiest way to do this is to loop over the yarns and assign the same properties to each yarn one by one. The syntax for looping over <code>Yarns</code> is shown here:
 
 
 
# Loop over all the yarns in the list
 
for Yarn in Yarns:
 
 
 
Inside the loop, the variable <code>Yarn</code> refers to the current yarn in the list. So within the loop we just assign properties to <code>Yarn</code> and they will be applied to all the yarns in the list. In python the begining and end of a loop are defined by indentation, hence the following lines are indented to represent the contents of the loop.
 
 
 
Let us define periodic cubic spline interpolation between the nodes:
 
 
 
    # Set the interpolation function
 
    Yarn.AssignInterpolation(CInterpolationCubic())
 
 
 
This is done with the function <code>AssignInterpolation</code> which takes an instance of a class derived from <code>CInterpolation</code>. In this case we used <code>CInterpolationCubic</code> to specify periodic cubic spline interpolation.
 
 
 
Next we need to define a cross section for the yarn, to keep things simple a constant cross section all along the length of the yarn will be defined:
 
 
 
    # Assign a constant cross-section all along the yarn of elliptical shape
 
    Yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(0.18, 0.04)))
 
 
 
The function <code>AssignSection</code> takes an instance of a class derived from <code>CYarnSection</code>. In this case we used <code>CYarnSectionConstant</code> which in turns take an instance of a class derived from <code>CSection</code> as a constructor. <code>CSectionEllipse</code> defines an elliptical cross section with given width and height defined by the first and second parameters respectively.
 
 
 
    # Set the resolution of the surface mesh created
 
    Yarn.SetResolution(20)
 
 
 
This line sets the resolution of the surface mesh created. The first parameter to the function <code>SetResolution</code> represents the number of points around a cross section. The number of points along the length of the yarns is automatically calculated such that the distance between points is similar to around the cross section.
 
 
 
Next we must add repeat vectors to define how the yarns are repeated.
 
 
 
    # Add repeat vectors to the yarn
 
    Yarn.AddRepeat(XYZ(0.44, 0, 0))
 
    Yarn.AddRepeat(XYZ(0, 0.44, 0))
 
 
 
The function <code>AddRepeat</code> takes an instance of the class <code>XYZ</code>. As we saw earlier the class <code>XYZ</code> is constructed with 3 numbers defining the X, Y and Z components.
 
 
 
Finally the yarn is fully defined, it can now be added to <code>Textile</code>:
 
 
 
    # Add the yarn to our textile
 
    Textile.AddYarn(Yarn)
 
 
 
This is the end of the loop, hence the following lines return to the original indentation. Now let's define a Domain within which the textile will be placed:
 
 
 
Textile.AssignDomain(CDomainPlanes(XYZ(0, 0, -0.02), XYZ(0.44, 0.44, 0.07)))
 
 
 
The function <code>AssignDomain</code> takes an instance of a class derived from <code>CDomain</code>. In this case we will create a box shaped domain, this can be accomplished by using the class <code>CDomainPlanes</code>. A box can be created by passing in opposite corners of the box (the minimum and maximum coordinates). This is done again with the class <code>XYZ</code>.
 
 
 
And finally <code>Textile</code> must be added to so that it can be rendered. Each Textile added must be assigned a name to identify it, this is the name that will appear at the top in the TexGen GUI. This name can either be generated automatically or we can specify it explicitly like so:
 
 
 
# Add the textile with the name "polyester"
 
AddTextile("polyester", Textile)
 
 
 
That's it! You now have the knowledge to create any type of fabric imaginable. Well, almost. The model created here is pretty simple, there is plenty of oppertunity to create more complex shapes. For example non-constant cross sections can be defined, complex domain shapes defined by arbritrary planes, different interpolation functions.
 
 
 
Here is the completed script:
 
 
 
# Create a textile
 
Textile = CTextile()
 
 
# Create a python list containing 4 yarns
 
Yarns = [CYarn(), CYarn(), CYarn(), CYarn()]
 
 
# Add nodes to the yarns to describe their paths
 
Yarns[0].AddNode(CNode(XYZ(0, 0, 0)))
 
Yarns[0].AddNode(CNode(XYZ(0.22, 0, 0.05)))
 
Yarns[0].AddNode(CNode(XYZ(0.44, 0, 0)))
 
 
Yarns[1].AddNode(CNode(XYZ(0, 0.22, 0.05)))
 
Yarns[1].AddNode(CNode(XYZ(0.22, 0.22, 0)))
 
Yarns[1].AddNode(CNode(XYZ(0.44, 0.22, 0.05)))
 
 
Yarns[2].AddNode(CNode(XYZ(0, 0, 0.05)))
 
Yarns[2].AddNode(CNode(XYZ(0, 0.22, 0)))
 
Yarns[2].AddNode(CNode(XYZ(0, 0.44, 0.05)))
 
 
Yarns[3].AddNode(CNode(XYZ(0.22, 0, 0)))
 
Yarns[3].AddNode(CNode(XYZ(0.22, 0.22, 0.05)))
 
Yarns[3].AddNode(CNode(XYZ(0.22, 0.44, 0)))
 
 
# Loop over all the yarns in the list
 
for Yarn in Yarns:
 
 
    # Set the interpolation function
 
    Yarn.AssignInterpolation(CInterpolationCubic())
 
 
    # Assign a constant cross-section all along the yarn of elliptical shape
 
    Yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(0.18, 0.04)))
 
 
    # Set the resolution of the surface mesh created
 
    Yarn.SetResolution(20)
 
 
    # Add repeat vectors to the yarn
 
    Yarn.AddRepeat(XYZ(0.44, 0, 0))
 
    Yarn.AddRepeat(XYZ(0, 0.44, 0))
 
 
    # Add the yarn to our textile
 
    Textile.AddYarn(Yarn)
 
 
# Create a domain and assign it to the textile
 
Textile.AssignDomain(CDomainPlanes(XYZ(0, 0, -0.02), XYZ(0.44, 0.44, 0.07)))
 
 
# Add the textile with the name "polyester"
 
AddTextile("polyester", Textile)
 
 
 
And the result:
 
 
 
[[Image:Example2.png]]
 
 
 
===Example 3: A 3d weave===
 
This example is similar to the [[Scripting Guide#Example 2: Another plain weave (the hard way)|Example 2]] in that the yarns will be defined by nodes. This time we will create a 3d woven fabric that looks like this:
 
 
 
[[Image:Example3.png]]
 
 
 
We start by defining a new CTextile instance:
 
 
 
# Create a textile
 
Textile = CTextile()
 
 
 
Before starting to define the geometry using TexGen it is helpful to define a list of parameters which may need to be changed later. These typically include spacing between yarns and yarn dimensions:
 
 
 
# Define some parameters
 
# Spacing between weft yarns
 
sx = 2
 
# Spacing between warp yarns
 
sy = 0.8
 
# Vertical distance between yarns at cross overs
 
sz = 0.16
 
 
# Width of the weft yarns is less than the weft spacing
 
weftyarnwidth = 1.2
 
# Width of the warp yarns set equal to the warp spacing
 
warpyarnwidth = sy
 
# Yarn height equal to the vertical distance between yarns at cross overs
 
yarnheight = sz
 
 
 
It is a good idea to define these up front rather than hard coding them in the rest of the script because if you want to tweak any parameters they can easily be located and will only need to be changed once. Lets start by defining the warp stuffer yarns, these are fairly easy to define since they all straight and parallel to each other:
 
 
 
# Create warp stuffer yarns
 
for i in range(3):
 
    yarn = CYarn()
 
    yarn.AddNode(CNode(XYZ(0, 0, 2*i*sz)))
 
    yarn.AddNode(CNode(XYZ(2*sx, 0, 2*i*sz)))
 
 
    yarn.AssignInterpolation(CInterpolationCubic())
 
    yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(warpyarnwidth, yarnheight)))
 
    yarn.SetResolution(20)
 
    yarn.AddRepeat(XYZ(2*sx, 0, 0))
 
    yarn.AddRepeat(XYZ(0, 2*sy, 0))
 
 
    Textile.AddYarn(yarn)
 
 
 
Next we define the weft stuffer yarns, again these are easy to define:
 
 
 
# Create weft stuffer yarns
 
for i in range(4):
 
    yarn = CYarn()
 
    yarn.AddNode(CNode(XYZ(0, 0, (2*i-1)*sz)))
 
    yarn.AddNode(CNode(XYZ(0, 2*sy, (2*i-1)*sz)))
 
 
    yarn.AssignInterpolation(CInterpolationCubic())
 
    yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(weftyarnwidth, yarnheight)))
 
    yarn.SetResolution(20)
 
    yarn.AddRepeat(XYZ(sx, 0, 0))
 
    yarn.AddRepeat(XYZ(0, 2*sy, 0))
 
 
    Textile.AddYarn(yarn)
 
 
 
And finally we need to insert the binder yarns. Making clever use of the repeat vectors it is only necessary to define a single instance of the binder yarn.
 
 
 
# Create warp binder yarns
 
top = 6*sz
 
bottom = -2*sz
 
 
oh = 0.5*weftyarnwidth+0.12
 
ov = 0.8*sz
 
 
yarn = CYarn()
 
yarn.AddNode(CNode(XYZ(0, sy, top)))
 
yarn.AddNode(CNode(XYZ(oh, sy, top-ov)))
 
yarn.AddNode(CNode(XYZ(sx-oh, sy, bottom+ov)))
 
yarn.AddNode(CNode(XYZ(sx, sy, bottom)))
 
yarn.AddNode(CNode(XYZ(sx+oh, sy, bottom+ov)))
 
yarn.AddNode(CNode(XYZ(2*sx-oh, sy, top-ov)))
 
yarn.AddNode(CNode(XYZ(2*sx, sy, top)))
 
 
yarn.AssignInterpolation(CInterpolationBezier())
 
yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(warpyarnwidth, yarnheight)))
 
yarn.SetResolution(20)
 
yarn.AddRepeat(XYZ(2*sx, 0, 0))
 
yarn.AddRepeat(XYZ(sx, 2*sy, 0))
 
 
Textile.AddYarn(yarn)
 
 
 
Now that the geometry is defined we shall define a domain and add the textile so that TexGen knows about it.
 
 
 
Textile.AssignDomain(CDomainPlanes(XYZ(-0.5*sx,-0.5*sy,bottom-sz), XYZ(1.5*sx,3.5*sy,top+sz)))
 
 
# Add the textile to our TexGen singleton
 
AddTextile(Textile)
 
 
 
The completed scripts is shown below:
 
 
 
# Create a textile
 
Textile = CTextile()
 
 
# Define some parameters
 
# Spacing between weft yarns
 
sx = 2
 
# Spacing between warp yarns
 
sy = 0.8
 
# Vertical distance between yarns at cross overs
 
sz = 0.16
 
 
# Width of the weft yarns is less than the weft spacing
 
weftyarnwidth = 1.2
 
# Width of the warp yarns set equal to the warp spacing
 
warpyarnwidth = sy
 
# Yarn height equal to the vertical distance between yarns at cross overs
 
yarnheight = sz
 
 
# Create warp stuffer yarns
 
for i in range(3):
 
    yarn = CYarn()
 
    yarn.AddNode(CNode(XYZ(0, 0, 2*i*sz)))
 
    yarn.AddNode(CNode(XYZ(2*sx, 0, 2*i*sz)))
 
 
    yarn.AssignInterpolation(CInterpolationCubic())
 
    yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(warpyarnwidth, yarnheight)))
 
    yarn.SetResolution(20)
 
    yarn.AddRepeat(XYZ(2*sx, 0, 0))
 
    yarn.AddRepeat(XYZ(0, 2*sy, 0))
 
 
    Textile.AddYarn(yarn)
 
 
# Create weft stuffer yarns
 
for i in range(4):
 
    yarn = CYarn()
 
    yarn.AddNode(CNode(XYZ(0, 0, (2*i-1)*sz)))
 
    yarn.AddNode(CNode(XYZ(0, 2*sy, (2*i-1)*sz)))
 
 
    yarn.AssignInterpolation(CInterpolationCubic())
 
    yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(weftyarnwidth, yarnheight)))
 
    yarn.SetResolution(20)
 
    yarn.AddRepeat(XYZ(sx, 0, 0))
 
    yarn.AddRepeat(XYZ(0, 2*sy, 0))
 
 
    Textile.AddYarn(yarn)
 
 
# Create warp binder yarns
 
top = 6*sz
 
bottom = -2*sz
 
 
oh = 0.5*weftyarnwidth+0.12
 
ov = 0.8*sz
 
 
yarn = CYarn()
 
yarn.AddNode(CNode(XYZ(0, sy, top)))
 
yarn.AddNode(CNode(XYZ(oh, sy, top-ov)))
 
yarn.AddNode(CNode(XYZ(sx-oh, sy, bottom+ov)))
 
yarn.AddNode(CNode(XYZ(sx, sy, bottom)))
 
yarn.AddNode(CNode(XYZ(sx+oh, sy, bottom+ov)))
 
yarn.AddNode(CNode(XYZ(2*sx-oh, sy, top-ov)))
 
yarn.AddNode(CNode(XYZ(2*sx, sy, top)))
 
 
yarn.AssignInterpolation(CInterpolationBezier())
 
yarn.AssignSection(CYarnSectionConstant(CSectionEllipse(warpyarnwidth, yarnheight)))
 
yarn.SetResolution(20)
 
yarn.AddRepeat(XYZ(2*sx, 0, 0))
 
yarn.AddRepeat(XYZ(sx, 2*sy, 0))
 
 
Textile.AddYarn(yarn)
 
 
Textile.AssignDomain(CDomainPlanes(XYZ(-0.5*sx,-0.5*sy,bottom-sz), XYZ(1.5*sx,3.5*sy,top+sz)))
 
 
# Add the textile to our TexGen singleton
 
AddTextile(Textile)
 
 
 
===Saving to TG3 file format===
 
TexGen has it's own file format for storing textile geometry with the extension .tg3. For more details on this file format please read the [[TG3 File Format]] page. Any textile models saved to this file format can be reloaded at a later time however it is also a good idea to keep the python script used to generate the geometry in case modifications need to be made. To save such a file it is simply a matter of adding an additional like at the end of your script like so:
 
 
 
SaveToXML("MyTextile.tg3")
 
 
 
The first parameter is the name of the file to save, note that if the .tg3 extension is omitted then it will automatically be appended for you. The second parameter is optional and if used should be the name of the textile to save, this is useful if you have several textiles loaded at once (i.e. you called AddTextile more than once) and you only want to save one of them. Note that if you don't specify the second parameter and you do have several textiles loaded then it will save all of them to a single .tg3 file. The third parameter determines how much information is saved in the .tg3 file, see the [[TG3 File Format]] for more details.
 

Revision as of 11:34, 15 April 2008

Python Interface

Python is a high level interpreted programming language. In this case it is used as a scripting language to allow easy access to TexGen functionality. Python has been embedded in the TexGen GUI which allows the GUI to run python scripts. The goal of this tutorial is not to teach Python programming, there are plenty of resources online for that. A few of them are listed below:

An advanced knowledge of Python is not needed in order to write simple TexGen scripts. However, bear in mind that Python is a very powerful language with many libraries included for performing common tasks.

A series of tutorials on getting started with using Python in conjunction with TexGen are provided below. They have been written in such a way that they are best read sequentially since each one follows on from the previous: