Computerized Pattern Generation

iconUsing Python Scripts

The scripts included with this article are designed to be used with python, and require the additional packages numpy and dxfwrite. Numpy is a standard enough package that it usually comes with python, but dxfwrite is an optional, third party package, and most users will need to install it separately. To view, and manipulate the DXF files, I suggest using DraftSight, as it is available for Macs, Windows, and Linux. The base packages are freely downloadable from these links here.

Python  |  NumPy  | dxfwrite  | DraftSight

For installation instructions for Mac, Windows and Linux, as well as a beginner's guide to using python, The Hitchhiker’s Guide to Python should be your first stop. (Editor's Note: As Jeremy's instructions below are for a Mac, we've prepared a step-by-step easy install and script run guide for Windows, you can download it HERE (pdf) )

I'm not in the position to teach python here, though I can respond to specific questions by email or in the forums. One thing that I should point out to curious readers who wish to cut and paste code, however, that python is whitespace sensitive. In particular, python scripts use the tab character to structure code into classes, functions and blocks.
For instance, this script has two functions. The first prints a greeting to the screen, The second calculates the nth integer in the Fibonacci Sequence. The indented statements are the constituents of each function—without the indents, it is not very clear to either the reader or the compiler which statements belong to each functions. Unlike in C, C++ or java, curly braces (“{“,”}”) are not meaningful delineators of blocks.

          def helloWorld():
          print("helloWorld")
          def fib(n):
          a,b = 1,1
          for i in range(n-1):
          a,b = b,a+b
          return a

          helloWorld()
          print(fib(9))

          typhon:~ jeremy$ python pythontest.py
          helloWorld
           34

The statement
    print "helloWorld"
is part of the HelloWorld function, and so it is indented with a tab. Similarly,
    a,b = b,a+b
is part of the for i in range(n-1): loop, and so it is indented with a further tab character. Paying attention to whether blocks of sample code are indented properly will save you a lot of grief, when following this article and others.

If in doubt, as to whether your python installation includes numpy, you can test it by typing

    jeremy$ python

Please note: Depending on your computer system, your command line will vary. The author is using a Mac, and his computer's name is "jeremy", jeremy$ is the start of his command line in the Terminal app for python. Windows users would see a >

Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

    >>> import numpy

If you received the error message similar to:
    Traceback (most recent call last):
    File "", line 1, in
    ImportError: No module named numpy

You'll need to install Numpy, as well as Dxfwrite. 

You may be able to use the “pip” program to install these packages.

jeremy$ sudo pip install dxfwrite
Downloading/unpacking dxfwrite
  Downloading dxfwrite-1.2.0.tar.gz (101kB): 101kB downloaded
  Running setup.py (path:/private/tmp/pip_build_root/dxfwrite/setup.py) egg_info for package dxfwrite
    
Installing collected packages: dxfwrite
  Running setup.py install for dxfwrite
    
Successfully installed dxfwrite
Cleaning up...

 

Download all the custom corset python scripts (zip) here

 

Once these packages are installed, you can run the script corsets.py, and enter in custom measurements.

The following measurements correspond to a slightly larger standard size—Manniquen 50, though you can enter in measurements that correspond to your client.

typhon:corsets jeremy$ ./corsets.py

You will then see the following set of prompts for measurements. Enter in your measurement, and press enter. The next prompt will appear. I recommend entering in these base measurements the first time you run the script. 

Enter Measurements in Centimeters
Back Length 40
Armpit Height 23
Neck to Nipple Line 24
Front Length 42
Half Waist Circumference 36
Half Bust Circumference 59
Half Hip Circumference (12cm below the waist) 57
Half Hip Circumference (20cm below the waist) 61
created customtailored.dxf
created customcup.dxf
created customback.dxf

 

After running the script, it outputs these files:

  • customtailored.dxf corresponds to a customized pattern for the front of the tailored corset,
  • customcups.dxf, to a customized pattern for the front of the corset with cups,
  • customback.dxf, to a customized back pattern, shared by both types of corset.

If you run the script again, these pattern files will be replaced with new pattern files, corresponding to the most recent set of measurements, so you may wish to rename the pattern files you wish to keep, so they are not overwritten.

 

Explanation of the scripts

Each of the three scripts mentioned here  contains two main subroutines-- makePoints, which calculates where the points of a pattern should be placed, and makeLines, which connects them using lines, arcs, and complex curves.

Points can be placed according to the following rules.

Fixed: places the point at an arbitrary point on the paper. This is usually used, once, to set an origin point, and all other points are placed in relation to the origin, or to other points.

Example:
self.fixedPoint("FP",0,0)

This places a point labeled FP at coordinates 0,0.

Up: places a point above another point, at a specified distance.

Example:
self.upPoint("UP","A",5)

This places a point labeled UP five units above A.

Down: places a point below another point, at a specified distance.

Example:
self.downPoint("DP","A",5)

This places point labeled DP five units below A.

Left: places a point to the left of another point, at a specified distance.

Example:
self.leftPoint("LP","A",5)

This places a point labeled LP five units to the left of A.

Right: places a point to the right of another point, at a specified distance.

Example:
self.rightPoint("RP","A",5)

This places a point five units to the right of A.

Displacement: places a point at x y coordinates relative to another point.

Example:
self.displacementPoint("DP","A", 3.0,5.0)

This places a point labeled DP three units to the right of, and five units above A.

Direction: places a point in an arbitrary direction from a point, at a specified distance.

Example:
self.directionPoint("DP","A", 135,5)

This places a point labeled DP five units away from A, in the direction of 135 degrees.

A note on directions: In this scheme, the compass rose is not the same as the familiar N=0, E=90, S= 180, W=270 standard used on maps.

My standard is UP=90, DOWN=270, LEFT= 180, RIGHT=0, for reasons having to do with how trigonometry is handled by the computer. For clarity's sake, I prefer upPoint, downPoint, leftPoint and rightPoint, but as some other functions do rely on measurements in degrees, it's worth pointing out here.

Along: places a point along a line specified by two points A, B, at a specified distance from B.

Example:
self.alongPoint("AP","A","B", 4.0)

Places a point labeled AP 4 units away from A along the line defined by A B.

This function can be used to divide a line into equal parts,  for instance, when placing the two front darts of a bodice.

self.alongPoint("p21","p13","G", self.dist(“p13”,”G”)/3.0 +0.5)
self.alongPoint("p22","p13","G", self.dist(“p13”,”G”)/3.0*2.0)

self.dist is a function that returns the distance between two points, so these two functions have the effect of dividing the line p13-G into thirds. p21 is half an inch closer to G than this, p22 lies exactly at the two thirds mark.

Extend: extends a line specified by two points, A and B, by a specified distance beyond B.

Example:
self.alongPoint("EP","A","B", 4.0)

Places a point 4 units beyond B, along the continuation of the line A-B.

This function is particular useful  for constructing basques and skirts.

Mid: places a point at the midpoint of points A and B.

Example:
self.midPoint("MP","B","A")

Places a point labeled MP midway between points B and A.

This is equivalent to

self.alongpoint(“MP”,”B”,”A”, self.dist(“B”,”A”)/2.0)

but with less typing.

Perpendicular: places a point a certain distance from B, along a line perpendicular to the line A – B.

Example:
self.perpendicularPoint("PP","A","B", 2.0)

places a point labeled “PP” 2.0 units from B, along a line perpendicular to the line AB.

If the line B-PP points exactly opposite from the direction you intend, it is a simple matter to specify a negative direction.

self.perpendicularPoint("PP2","A","B", -2.0)

Thus,

self.perpendicularPoint("PP","A","B", 2.0)
self.perpendicularPoint("PP2","A","B", -2.0)

PP2, B, and PP lie on a straight line perpendicular to the line AB.

Parallel: places a point a certain distance from C, along a line perpendicular to the line A – B.

Example:
self.parallelPoint("PP","A","B","C", 8.0)

Places a point labeled PP 8 units from C, along a line parallel to A--B.

In the patterns discussed above, the front upper and lower hiplines were parallel to the front waistline, which was slanted  upwards towards the side seam.

Angle-angle: places a point a certain angle from A and a certain angle from B.

Example:
self.angleAnglePoint("AA","C",135,"B", 45)

Here, AA is placed at the intersection of a line extended from C at 135 degrees, and a line extended from B at 45 degrees. Note that the angles are measured as explained under directionpoint, e.g down is 270, left is 180, and so on.

Here the following lines instructions construct a square,

self.fixedPoint("A",1,1)
self.directionPoint("B","A", 135,6)
self.perpendicularPoint("C","B","A", self.dist("B","A"))
self.angleAnglePoint("AA","C",self.degrees("A","B"),"B", self.degrees("A","C"))

This instruction may be useful if you need to construct a rectangle that is not oriented along the standard left/right up/down axes,

T-intersection: places a point at the intersection of a line extended from A at a certain angle and the line B-C.

Example:
self.teeIntersectionPoint("TI","D",180, "A", "C")

Places a point named TI at the intersection of a line extended to the left (180 degrees) from D, and a line connecting A and C.

This point comes in very handy in modeling the back of a woman's bodice. Usually, the back line is on the diagonal to better fit the curve of the back, but it's useful to mark where the back width line and bust line intersect with the newly inclined center back seam.

Intersection: places a point at the intersection of lines A—B with C—D.

Example:
self.intersectionPoint("IP","A","D","B","C")

places a point named IP at the intersection of a line connecting A to D with a line connecting B to C,

Circle line intersection: places a point along a line extended from A at a certain angle, such at that it is a certain distance from B.

Example:
self.circleLineIntersectionPoint("CL","D", "B", 270, 1.50)

Places a point named ”CL” at the point where a line drawn from D first crosses a circle of 1.5 units in diameter centered at B.

circle line segment intersection: places a point along a line through A and, such at that it is a certain distance from C.

Example:
self.circleLSIntersectionPoint("CLS","B","C","D",3.0)

Places a point named ”CLS” at the point where a line drawn from C to D first crosses a circle of 2.0 units in diameter centered at B.

Circle circle intersection: places a point a certain distance from A and a certain distance from B.

Example:
self.circleCircleIntersectionPoint("CC","D", 2.5, "B",  1.50, False)

Places a point named CC  2.5 units from D, and 1.5 units from B.

Since distinct circles can intersect each other in zero, one, or two points, the last variable serves to distinguish between the two points of intersection. If you find out that the computer is using the wrong point of intersection, you can change it to from True, to False.

Perpendicular bisector: places a point a certain distance from the midpoint of A and B, along a line perpendicular to the line A – B.

Example:
self.perpendicularBisectorPoint("PB","B","A", 6.0)

Places a point named PB on the perpendicular bisector between A and B, 6 units away from the midpoint.

Note: the distance can be negative as well, following the scheme of the perpendicularpoint above.

If the drafting method warrants the addition of any other schemes, more algorithms can easily be added. The geometry calculations are contained in the file patterndxf.py; pattern.py wraps up this in a slightly nicer syntax that lets the programmer refer to points by name.

For instance, this is a typical function in pattern.py

 def midPoint(self,name,pointA, pointB):
        """ places a point halfway between points A and B
            : param str name: name of the new point
            : param str pointA: name of the existing point A
            : param str pointB: name of the existing point B
            """
        self.points[name]=pat.midPointVector(self.points[pointA],self.points[pointB])

and this is the corresponding function in patterndxf.py

def midPointVector(vectorA, vectorB):
    x=(vectorA[0]+vectorB[0])/2.0
    y=(vectorA[1]+vectorB[1])/2.0
    return (x,y)

Let's apply this code to a simple pattern-- a chemise in two pieces, taken from the book Coupe de Lingerie, pp 29-33 “Cinquième Leçon: Chemise de Jour talliée en two pièces”.

The following sample measurements are used:
BackLength 37
Total Length 115
Half the width of the back 16
Half the width of the front 17
Half the bust circumference 48

The instructions are as follows:

For the back
Measure the total length of the garment below point 1 and mark this point 3 (115cm),
Measure 3cm to the left of point 1, and mark this point 2,
Measure 1/4 of the back length down from point 2, and mark this point 4 (9.3cm),
Measure half of the back width to the left of point 4, and mark this point 5 (16cm),
Measure 1/8 of the back length up from and half a centimeter to the left of point 5 and mark this point 5a (4.6cm),
Measure out the distance between 5 and 5a to the left and 1.5cm up from point 2 and mark this point 2a,
Measure 1/2 of the back length down from point 2, and mark this point 6 (18.5cm),
Measure half of the half bust circumference to the left of point 6 and and mark this point 7,
Measure 45cm to the left of point 3 and mark this point 8,
Measure 3cm from 8 towards 7 and mark this point 9,
Measure 4cm along the line from 5a to 2a and mark this point neckTop,
Measure down from point 1 the distance from 2a to neckTop, and mark this point neckCenter (14.5cm),
Draw the curve of the armhole from 5a to 5 and 7,
Mark the intersection of the waistline with the 7-8 line as point 10,
From point 10, Measure 2cm to the right and 2cm up and mark point 10a,
Draw the curve of the armhole from 5a to 5 and 7,
Draw a curve from 7 to 10a to 9,
Draw an gentle arc from 9 to 3,
Draw a straight line from 3 to neckCenter,
Draw the neckline from neckCenter to neckTop,
Draw a line from neckTop to 5a.

For the front
Measure 5cm to the right of point 1, and mark this point 2,
Measure one fourth of the half front width plus 1cm  down from point 2 and mark this point 3 (5.3cm),
Measure one half of the half front width  to the right  of point 2 and one centimeter up. Mark this point 4 (8.5cm),
Calculate the distance from point 2a to 5a on the back plus 1/10 of the half bust circumference. Point 5 lies on a line to the right of point 3, that distance away from point 5,
Measure 4cm from point 5 towards point 4 and mark this point 6,
Measure 1/2 of the back length down from point 2, and mark this point 9 (18.5cm),
Measure half of the half bust circumference plus 5cm to the right of point 9 and and mark this point 10,
Measure 1/4 of the back length down from point 2 and mark this point 7a,
Extend a line down from 5 and left from 7a and mark the point of their intersection as point 7,
Measure 2cm to the left of point 7 and mark this point 8,
Measure 115cm down from point 1 and mark this point 11,
Measure 45cm to the  right of point 11 and mark this point 12,
Measure 1/10 of the half bust down from point 10 and mark this point 13,
Mark the intersection of the waistline with the 10-12 line as point 14,
From point 14, Measure 2cm to the left and 2cm up and mark point 14a,
Draw the curve of the armhole from 5 to 8 and 10,
Draw a curve from 10, to 14a, through 12,
Connect 12 to 13 with a gentle arc,
Connect 13 to neckCenter with a straight line,
Draw the neck from neckCenter to 6,
Draw a straight line from 6 to 5.

 

Programming the script

Open up a new file. Call it chemise.py  (This is also available in the zip file download found above)

This is the basic skeleton of the script.

#!/usr/bin/env python
import sys
sys.path.append('..')
from dxfwrite import DXFEngine as dxf
from dxfwrite.dimlines import dimstyles, LinearDimension
from pattern import pattern

class chemise(pattern):

    def __init__(self,  filename, largepoints=False, **kwargs):
        pattern.__init__(self,  filename, largepoints=False)
        if(kwargs):
            self.m=kwargs["measurements"]
        else:
            self.m={}
    def makePoints(self):
        return
    def makeLines(self):
        return

if __name__=="__main__":
    myMeasurements={}
    
    ch=chemise("chemise.dxf",measurements=myMeasurements)

    ch.makeGeometry()
    ch.makeViewport()
    ch.makeDXF()


The next step is to type in the sample measurements:

if __name__=="__main__":
    myMeasurements={}
    myMeasurements["backLength"]=37
    myMeasurements["fullLength"]=115
    myMeasurements["halfBackWidth"]=16
    myMeasurements["halfFrontWidth"]=17
    myMeasurements["halfBust"]=48
    ch=chemise("chemise.dxf",measurements=myMeasurements)
…

When trying to computerize old drafting instructions, it's good practice to use the measurements provided, so that you can take advantage of the writer's example calculations, as well as produce a drawing that looks like the provided illustration. If you are exceptionally lucky, the printed illustration will be to scale, and rectilinear as well. But the process of scanning, as well as the original printer's liberties may limit the usefulness of taking calipers and rulers to the original pattern.

Once you have done all this, it's time to move on to the back pattern.

All the points are calculated in the makePoints function. As a convenience, the first statement should be

makePoints(self):
    m=self.m

The first point (b1) can be placed anywhere, so
    self.fixedpoint(“b1”,0,0)

Measure 3 cm to the left of point 1, and mark this point 2. This measurement can be between 3 and 5 cm, and is used for pleating or ruffles. The most straightforward approach is to use a leftPoint instruction, shown here with a value of 3 cm.

self.leftPoint("b2","b1", 3.0)

Measure the total length of the garment below point 1 and mark this point 3 (115cm)

Likewise, this calls for a downPoint instruction But instead of hard coding 115.0, it's more practical to leverage the myMeasurements["fullLength"]=115 instruction. The way to do this is as follows.

self.downPoint("b3", "b1",  m["fullLength"])

Because of the statement m=self.m, this is equivalent to  self.downPoint("b3", "b1",  self.m["fullLength"])
but with less typing.

The end result is by changing one line of code, or even by prompting the use for custom measurements in another part of the script, we can lengthen or shorten the chemise quite easily.

Measure ¼ of the back length down from point 2, and mark this point 4 (9.3cm)

    self.downPoint("b4","b2", m["backLength"]/4.0)

Measure half of the back width to the left of point 4, and mark this point 5 (16cm)

    self.leftPoint("b5", "b4", m["halfBackWidth"])

Measure 1/8 of the back length up from and half a centimeter to the left of point 5 and mark this point 5a (4.6cm)
This is slightly more complex than the simple upPoint, downPoint, left Point and rightPoint algorithms. It calls for a displacement point.

    self.displacementPoint("b5a", "b5", -0.5,  m["backLength"]/8.0)
        
positive x components are to the right, negative x components are to the left
positive y components are up, negative y components are down.

Measure out the distance between 5 and 5a to the left and 1.5cm up from point 2 and mark this point 2a

Since the distances between points changes based on the measurements provided, the script must have a way of measuring the distance between points. This is accomplished through the dist function. Given the names of two points, it returns the distance between them. Note that since this distance is plotted to the left of point b2, the negative value of this distance is used.

    self.displacementPoint("b2a", "b2", -self.dist("b5","b5a"),  1.5)

Measure 1/2 of the back length down from point 2, and mark this point 6 (18.5cm)

    self.downPoint("b6", "b2", m["backLength"]/2.0)

Measure half of the half bust circumference to the left of point 6 and and mark this point 7

    self.leftPoint("b7", "b6", m["halfBust"]/2.0)

Measure 45cm to the left of point 3 and mark this point 8.

    self.leftPoint("b8","b3",45.0)

The sweep of the chemise's skirt is hard coded, though you may wish to make this part of the measurement process For instance

    myMeasurements["skirtWidth"]=45
    self.leftPoint("b8","b3",m["skirtWidth"])

but this is left as an exercise for the user.

Measure 3cm from 8 towards 7 and mark this point 9

This calls for another new point type, the alongPoint. This measures 3cm along the b8 to b7 line, so as to curve the hemline a bit.

    self.alongPoint("b9","b8","b7", 3.0)

Mark the intersection of the waistline with the 7-8 line as point 10

It's necessary to first find the waistline. The patterns in this book are based on a series of parallel lines-- the collar line, the shoulder line, the torso line (ligne de carrure), the bust line, the waist line, etc. The collar line lies at the nape of the neck-- at the level of b1.

The waistline lies backLength below the collar line.

    self.downPoint("bwaist", "b1", m["backLength"])

Similarly, the bustline lies halfway between the collar line and the waistline. The torso line halfway between the bust and the collar line, and the shoulder line lies halfway between the torso line and the collar line.

You should be able to see that b1 lies on the collar line, b5a lies on the shoulderline , b4 lies on the torso line, b6 lies on the bust line.

Next, you need to mark the intersection of the waist line with a line drawn from b7 to b8. This calls for a tee intersection point

    self.teeIntersectionPoint("b10", "bwaist", 0, "b7","b8")

which intersects a line drawn to the left of point bwaist and intersects with a line drawn from b7 to b8.

From point 10, Measure 2cm to the right and 2cm up and mark point 10a. This allows for a slight indentation at the waist (or at the raised waist common among slips and petticoats, at any rate)/

This is a displacement point.

    self.displacementPoint("b10a","b10", 2.0,2.0)

The neck line can be drawn as desired.

Here, the neckline is constructed so that the shoulder strap is 4cm wide, and follows the curve of the neck at a consistent distance.

Measure 4cm along the line from 5a to 2a and mark this point neckTop.

    self.alongPoint("b_neckTop","b5a", "b2a", 4.0)

Measure down from point 1 the distance from 2a to neckTop and mark this point neckCenter (14.5cm)

    self.downPoint("b_neckCenter", "b1", self.dist("b2a","b_neckTop"))

All the points that describe the back have now been placed.  The points that describe the front are as follows

Point 1 can be paced anywhere, but for simplicities sake, it's simply placed 5cm to the right of b1.

    self.rightPoint("f1", "b1",5.0)

Measure 5cm to the right  of point 1, and mark this point 2
Like the back, there's a section that is reserved for pleats and ruffles. In this instance, the pleated section is 5cm wide (per side)

    self.rightPoint("f2", "f1",5.0)

The next points define the standard neckline, perhaps more importantly, the slope of the shoulder.

Measure one fourth of the half front width plus 1cm  down from point 2 and mark this point 3 (5.3cm)

    self.downPoint("f3","f2", m["halfFrontWidth"]/4.0 + 1.0)

Measure one half of the half front width to the right of point 2 and one centimeter up. Mark this point 4 (8.5cm)

    self.displacementPoint("f4", "f2", m["halfFrontWidth"]/2.0, 1.0 )

Calculate the distance from point 2a to 5a on the back plus 1/10 of the half bust circumference. Point 5 lies on a line to the right of point 3, that distance away from point 5

This method of finding the shoulder point is common to many drafts for constructing bodices. The software here uses a circle line intersection point. This may not be terribly obvious from the description but consider the following

Draw a straight line to the right of point 3. Now, imagine setting a compass to the width of the back shoulder plus 1/10 of the half bust circumference. (The traditional tool used to inscribe circles this large is called a “beam compass”.)

Place the point of the compass on the shoulder point-- point 4, and scribe an arc across the straight line.

Recalling that right is equivalent to zero degrees, and that b2 and b5a define the back shoulder

    self.circleLineIntersectionPoint("f5","f3","f4",0, self.dist("b2a","b5a")+ m["halfBust"]/10.0)

Measure 4cm from point 5 towards point 4 and mark this point 6

    self.alongPoint("f6","f5","f4", 4.0)

Measure half of the back length down from point 2, and mark this point 9 (18.5cm)

    self.downPoint("f9", "f2", m["backLength"]/2.0 )

Measure half of the half bust circumference plus 5 cm to the right of point 9 and and mark this point 10

    self.rightPoint("f10", "f9", m["halfBust"]/2.0+ 5.0)    

Measure one fourth of the back length down from point 2 and mark this point 7a

    self.downPoint("f7a", "f2", m["backLength"]/4.0 )

Extend a line down from 5 and right from 7a and mark the point of their intersection as point 7

This requires the use of the angle, angle point, which marks the intersection of two lines, each defined by a beginning point and a direction in degrees. Down from 5 is 270 degrees, right from 7a is 0 degrees.

    self.angleAnglePoint("f7", "f7a", 0, "f5", 270)

Measure 2 cm to the left of point 7 and  mark this point as 8

    self.leftPoint("f8","f7",2.0)

Measure the full length down from point 1 and mark this point as 11 (115 cm)

    self.downPoint("f11","f1", m["fullLength"] )

Measure 45 cm to the  right of point 11 and mark this point as 12

    self.rightPoint("f12", "f11", 45.0)

Measure 1/10 of the half bust down from point 10 and mark this point as 13

    self.downPoint("f13","f11", m["halfBust"]/10.0)

Mark the intersection of the waistline with the 10-12 line as point as 14

    self.downPoint("fWaist", "f1", m["backLength"])
    self.teeIntersectionPoint("f14", "fWaist", 0, "f12","f10")

From point 14, Measure 2 cm to the left and 2 cm up and mark point 14a

    self.displacementPoint("f14a","f14", -2.0, 2.0)

From point 1, measure the length from point 4 to point 6, and make point neckCenter

    self.downPoint("f_neckCenter", "f1", self.dist("f4","f6"))

After placing the points of the pattern it's time to connect the dots, preferably with curved lines that conform to the traditional hip curve, French curve, vary curve, etc. While it is possible to construct curves on a computer using the cubic, and quadratic curves, such curves are easier to place by eye, than by carefully coding all the tangents individually, so that they look nice when rendered with a variety of  individualized body measurements.

For instance, from a hand coded pattern for a the corset with bra cups:

        hipcurve.start(self.points["f23bot"], tangent=self.makeTangent("f23bot","f23"))
        hipcurve.append(self.points["f23"], tangent1=self.makeTangent("f23","f23bot"))
        hipcurve.append(self.points["f18"], tangent1=self.makeTangent("f12","f18"))
        hipcurve.append(self.points["f12"], tangent1=(-3,-3)

Is quite verbose, and requires a bit of trial and error.

To save time and effort, I have coded a few curve functions that should be appropriate for a variety of garments, not just this chemise.

They are:

    skirtbottom(self, side1, bottom1, bottom2,side2)

which draws a smooth arc for the bottom of skirts  and the like

    armscye(self,neck, shoulder, mid, side):

which draws in an armscye,

and

    neckline(self, shoulder, necktop, neckcenter)

which draws in a neckline.

These functions are supplemented by

    Line(self,paLabel,pbLabel):

which draws a straight line between two points

    Guide(self,paLabel,pbLabel):

which draws a dashed line between two points

    makeArc(self, a,b, distance):

which draws a circular arc between two points, with a rise equal to “distance”. This is very useful in putting in thin waist darts, or constructing the curve of bra cups.

More complex curves may be forthcoming in future versions of scripts, if there is a demand.

Draw the curve of the armhole from 5 to 7 and 10.

Draw a curve from 10, to 14 a, through 12. Connect 12 to 13 with a gentle arc.

Most of the drawing of lines should be done in the “makeLines” function, though this is largely to keep things clean.

Although it is possible to draw individual lines, curves, arc,s and so on, it is preferable to string these together into a complex polygon, one for each pattern piece. The chief advantage of doing this is in a CAD program, such as draftCAD, the individual pieces can be moved around more easily on the virtual page for printing, seam allowances can be added, and so on.

The instructions for the back say:

Draw the curve of the armhole from 5 to 7 and 10.
Draw a curve from 7 to 10a to 9.
Draw an gentle arc from 9 to 3
Draw the neckline from neckTop to neckCenter

The first thing to do is declare a list.

    back= list()

In this scheme, the curves are approximated as lists of points, with straight lines connecting them. An armscye can be made of 40 points or more, so on paper the “curve” appears fairly smooth.

Next, this list is extended by adding an armscye.

The first two points are those of the shoulder. The stroke from the shoulder to the side points needs to start out as perpendicular to the shoulder line, and specifying two points on the shoulder helps generate the curves initial tangent. The second point is the side seam of the armscye. The tangent is assumed to be perpendicular to the torso line. The fourth point is the side seam. Here the tangent is assumed to be parallel with the bust line.  Should these assumptions be unwarranted, I can easily change the algorithm

    back.extend(self.armscye("b2a", "b5a", "b5", "b7"))

Next, the side seam is added. This is a simple curve that curves in from the armhole point to the waist point, and then flares out to form the skirt. It's probably of limited usefulness outside of petticoats and chemises.

    back.extend(self.sideseam("b7","b10a","b9"))

Next, the skirt bottom is defined. The first variable is the line of the skirt side, followed by the bottom edge of the skirt, then the other bottom edge of the skirt, followed by the side. As with the armscye, the chief reason for including the first and forth variables is to supply tangents to control how curvy the arc should be.

    back.extend(self.skirtbottom("b10","b9", "b3", "bwaist"))

Next, the straight line from 3 to the neck line is drawn.

    back.append(self.points["b_neckCenter"])

Note that single points are appended, while curves are extended.

Then the neckline is defined

    back.extend(self.reversepoly(self.neckline("b5a", "b_neckTop", "b_neckCenter")))

“b5a” is the shoulder point-- it helps define how the neckline curves up into the shoulder line. Since the function generates a neckline starting from the shoulder to the center, but we need a neckline starting from the center and ending at the shoulder, it's necessary to flip the curve. Thus, the reversepoly command.

Finally, we connect b_neck_top to b5a with a straight line

    back.append(self.points["b5a"])

Once that is done,

    self.makeCurve(back)

adds it to the drawing

and for the front

    front=list()

Draw the curve of the armhole from 5 to 8 and 10.
front.extend(self.armscye("f4", "f5", "f8", "f10"))
Draw a curve from 10, to 14 a, through 12.

    front.extend(self.sideseam("f10","f14a","f12"))

Connect 12 to 13 with a gentle arc.

    front.extend(self.skirtbottom("f14","f12", "f13", "f9"))

Connect 13 to neckCenter with a straight line

    front.append(self.points["f_neckCenter"])

Draw the neck from neckCenter to 6

    front.extend(self.reversepoly(self.neckline("f5", "f6", "f_neckCenter")))

Draw a straight line from 6 to 5

    front.append(self.points["f5"])
    self.makeCurve(front)

The following lines, if added to the corsets.py script, will add some interactivity to the process

    m["halfBackWidth"]=float( input('Half the Width of the Back '))

    m["halfFrontWidth"]=float( input('Half the Width of the Front '))

    m["fullLength"]=float(input(' Full length of the Chemise '))
    c4=chemise4.chemise(" customchemise.dxf", measurements=m)

    c4.makeGeometry()
    c4.makeViewport()

    c4.makeDXF()

    print("created customchemise.dxf")

Thus

typhon:corsets jeremy$ ./corset.py
Enter Measurements in Centimeters
Back Length 36
Armpit Height 21
Neck to Nipple Line 20
Front Length 38
Half Waist Circumference 27
Half Bust Circumference 42
Half Hip Circumference (12 cm below the waist) 42
Half Hip Circumference (20 cm below the waist) 47
created customtailored.dxf
created customcup.dxf
created customback.dxf
Half the Width of the Back 14
Half the Width of the Front 15.5
Full length of the Chemise 115
created customchemise.dxf

creates four files:

  • customchemise.dxf (chemise pattern)
  • customback.dxf (the back pattern)
  • customcup.dxf, (the corset with cups, front and cup pieces)
  • customtailored.dxf (the tailored corset) customized to those particular measurements.

The four scripts (newcorsetback.py, newcsg.py, newtailored7.py, and chemise4.py) can be run directly, producing the following files: chemise.dxf, newcsg.dxf, newcorsetback.dxf, newtailored7.dxf, but according to built in sample measurements.

 

Sources

Lorentz and Lacroix Cours complet d'enseignement professionnel de la coupe du corset. Available for purchase here, and free here.
Lorentz and Lacroix Cours complet d’enseignement professionel de la Coupe de Lingerie Available for free here.

 

 

 

add

Gravatar
dazeoflaur 09.08.2014 02:45  
Yes No   Took one and only computer science class at Cornell - goes to show husband this article as he has more experience. :)  
 
Report comment
Gravatar
jerwin 09.08.2014 16:04  
Yes No   As the author, I'm willing to answer any questions you might have-- and to fix any bugs that may have crept in. A number of other computer programs besides DraftSight will handle dxf files, among them AutoCAD and Illustrator. Budget limitations prevent me from testing compatibility :)  
Last edited on 09.08.2014 16:04 by Jeremy Erwin
 
Report comment
Gravatar
kathtea 10.08.2014 14:28  
Yes No   Is it possible for you to add a chart/instructions on where exactly to measure for this generator? I'm trying various things but I feel like I am making mistakes.  
 
Report comment
Gravatar
kathtea 10.08.2014 14:58  
Yes No   Here are screenshots of my (failed?) attempt:-
http://i.gyazo.com/75f2639900a70237ef52e6da47954c6a.png
http://i.gyazo.com/baf727ab2f2c8d1f9c12fa0ba0a97396.png
http://i.gyazo.com/d19983083aaba75959b7d18d912e7235.png
 
 
Report comment
Gravatar
ivyrose 10.08.2014 00:42  
Yes No   Sure wish I knew what any of this meant, as it looks very useful!  
 
Report comment
Gravatar
jerwin 10.08.2014 03:39  
Yes No   ivyrose said :
Sure wish I knew what any of this meant, as it looks very useful!

Well, at the most basic level, if you run my scripts, and enter in custom measurements. you'll get a pattern drafted to your measurements (in DXF format, used by CAD programs). At a more advanced, level, you can take a pattern draft that you've found from original sources, e.g. Charles Hecklinger's ladies garments and end up with a program that will do the drafting for you.

 
 
Report comment
Gravatar
purplepincushion 10.08.2014 13:13  
Yes No   I am really hoping I can figure this stuff out because this would be such a useful way to approach the type of work I do. Thanks for tackling this. I am sure I will be back with questions later.  
 
Report comment
Gravatar
jerwin 10.08.2014 17:08  
Yes No   You're quite welcome. I'm willing to assist in any way that I can  
Last edited on 10.08.2014 18:59 by Jeremy Erwin
 
Report comment
Gravatar
kathtea 11.08.2014 01:55  
Yes No   Hello Jeremy! I can't find your comment here but I saw your reply via email, I've fixed the measurements and NOW I managed to get positive results!
Measurements http://i.gyazo.com/93fd2854bcd1c0f4d43d55011ee30423.png
Front http://i.gyazo.com/1aeabb3385bdb2edb0bc6dd0716c0221.png
Back http://i.gyazo.com/79f8f38f083164ca8f7480afad0f4a74.png

Thank you so much for creating this Python script. It would be amazing if you could make more for various corset styles e.g underbusts

Thank you once again!
 
 
Report comment
Gravatar
kathtea 11.08.2014 01:56  
Yes No   PS: I am even willing to pay for it!  
 
Report comment
 
  • Bold
  • Italic
  • Underline
  • Quote
  • Ordered List Unordered List
  • Add image
  • Add URL
  • Youtube Google
  • Smileys
  • :confused:
  • :cool:
  • :cry:
  • :laugh:
  • :lol:
  • :normal:
  • :blush:
  • :rolleyes:
  • :sad:
  • :shocked:
  • :sick:
  • :sleeping:
  • :smile:
  • :surprised:
  • :tongue:
  • :unsure:
  • :whistle:
  • :wink: