fe
folder,
and thus should be on the EVOLVERPATH
so Evolver can find them.
You read a script file into Evolver with the read command, for example
Enter command: read "3ds.cmd"In general, each script contains one main command, whose name is the same as the file name, e.g.
adjoint.cmd
contains the adjoint
command,
except for when this would result in an illegal name or a conflict with an
Evolver keyword. Each file has usage instructions in the comments in the top
of the file.
A list of the script files:
Of these, many people are particularly interested in scripts that can export files that other software can read, so here is a list of file export scripts. These generally work by running the command with the output re-directed to a file, for example
Enter command: read "collada.cmd" Enter command: collada >>> "filename.cda"Note that
>>>
results in over-writing any existing
file of the same name.
Usage: do_3ds >>> "filename.3ds"
Assumptions: 3D soapfilm model, linear model, not torus or symmetry group
(use the detorus
command if necessary to convert torus or symmetry
to unwrapped surface, but remember that detorus alters the surface).
Limited to 65535 facets.
Does facets only, not edges.
Facet color is frontcolor on both sides.
Ulrich Pinkall and Konrad Polthier, Computing Discrete Minimal Surfacee and Their Conjugates, Experim. Math. 2(1) (1993) 15-36
andKonrad Polthier, Conjugate Harmonic Maps and Minimal Surfaces.
The "adjoint" of a smooth minimal surface is another minimal surface isometric to the first that has normals in the same direction at each point but the infinitesimal surface element rotated 90 degrees about the normal. Schwartz' P and D surfaces are adjoints of each other.A "discrete minimal surface" is made up of flat triangles. It is called "conforming" if the vertices of adjacent triangles coincide, and "nonconforming" if adjacent triangles only meet at their midpoints. Polthier shows that if a conforming discrete minimal surface minimizes area, then it has an exact nonconforming adjoint.
The adjoint
command in this file takes a conforming surface and
calculates the nonconforming adjoint, then tweaks vertices to make it
conforming, so it is a legal Surface Evolver surface.
Assumptions:
Usage: adjoint
After adjoint
has been run, you can flip back and forth between the
original and the adjoint with the flip
command.
Usage: flip
Before running adjoint
, you can set the variable starte
to the number
of the edge whose midpoint will remain fixed in place; default is edge[1].
The angle of the Bonnet rotation is set by the variable bangle
, which
you may set to any degree value before doing adjoint
. The default
value of bangle is 90 degrees.
Also this file has the command write_conjugate
to write a datafile to
stdout that is the nonconforming discrete adjoint, with separated vertices.
Use this to see Polthier's idea in its true form.
Usage: write_conjugate >>> "filename.fe"
For a slightly more elaborate approach using complex numbers for the adjoint coordinates, which is faster for doing multiple arbitrary rotations, see adjointc.cmd. This file and adjointc.cmd have non-overlapping namespaces, so both can be loaded simultaneously.
See my page on
triply periodic minimal surface for examples created with adjoint
.
Ulrich Pinkall and Konrad Polthier, Computing Discrete Minimal Surfacee and Their Conjugates, Experim. Math. 2(1) (1993) 15-36
andKonrad Polthier, Conjugate Harmonic Maps and Minimal Surfaces.
The "adjoint" of a smooth minimal surface is another minimal surface isometric to the first that has normals in the same direction at each point but the infinitesimal surface element rotated 90 degrees about the normal. Schwartz' P and D surfaces are adjoints of each other.A "discrete minimal surface" is made up of flat triangles. It is called "conforming" if the vertices of adjacent triangles coincide, and "nonconforming" if adjacent triangles only meet at their midpoints. Polthier shows that if a conforming discrete minimal surface minimizes area, then it has an exact nonconforming adjoint.
The adjointc
procedure in this file takes a conforming surface and
calculates the nonconforming adjoint, then tweaks vertices to make it
conforming, so it is a legal Surface Evolver surface.
Assumptions:
adjointc
; but
fixed vertices and edges are ok.
Usage: adjointc( real bangle, integer origin_vertex )
Arguments:
bangle
- Bonnet rotation angle in degrees.
origin_vertex
- id of the vertex to be kept fixed.
After adjointc
has been run, one may do other Bonnet rotations more
quickly by calling bonnet_rotation()
Usage: bonnet_rotation(real bangle, integer origin_vertex )
Arguments:
bangle
- Bonnet rotation angle in degrees.
origin_vertex
- vertex to be kept fixed.
Also this file has the command "write_conj" to write a datafile to stdout that is the nonconforming discrete adjoint, with separated vertices. Use this to see Polthier's idea in its true form.
Usage: write_conj >>> "filename.fe"
For a slightly simpler approach using just real numbers for the adjoint coordinates, see adjoint.cmd. This file and adjoint.cmd have non-overlapping namespaces, so both can be loaded simultaneously.
See my page on
triply periodic minimal surfaces for examples of files adjointc
can be used with.
Assumptions and limitations:
Usage: ansys >>> "filename"
WARNING: This command modifies the surface by creating a lot of tiny facets. You should use only on a disposable copy of your surface.
Assumptions:
Usage:
bandcolor
and bandwidth
to desired values;
bandwidth
is
the width of the band in surface coordinates on one
side of an edge.
inband
to nonzero for those edges
to have band drawn along them.
makeband
.
read "band.cmd"; bandwidth := 0.003; bandcolor := black; set edge inband on_constraint topcon; makeband set edge inband on_constraint leftcon; makeband set edge inband original==1; makebandNote: If
makeband
has problems in corners and other tricky spots,
run makeband
several times on separate sets of edges.
When setting inband
for the later runs, make sure you
zero out inband
on the edges of the previous run.
Notice the conditions in the example are Boolean, applied to all edges.
Usage:
make_movie
to calculate rotations.
show_movie
to see screen display of Bonnet rotation.
movie
to see endlessly repeating display of Bonnet rotation.
postscript_movie
to create sequence of PostScript files.
The names of the PostScript files will be the datafilename with
the frame number appended.
This representation uses the 4th coordinate as the quaternion scalar component, for better mapping between R^3 and S^3 at quaternion unit.
Datafiles should be set up in 4 dimensions, with S^3 implemented as the level set constraint x^2 + y^2 + z^2 + w^2 = 1
Works best if starting edge starte is toward the center of the surface rather than on the outside.
Contained in this file:
s3_to_r3
:
r3_to_s3
: centralize(integer v_id)
: Assumptions and limitations:
Usage:
coff
and redirect output to a file.
Enter command: read "coff.cmd" Enter command: show facet where not fixed Enter command: coff >>> "filename.coff"
Assumptions and limitations:
Usage:
collada
and redirect output to a file.
Enter command: read "collada.cmd" Enter command: show facet where not fixed Enter command: collada >>> "filename.col"
Contents:
re_sqrt(real rex,real imx), im_sqrt(real rex, real imx)
re_sin(real rex,real imx), im_sin(real rex, real imx)
re_arcsin(real rex,real imx), im_arcsin(real rex, real imx)
re_incompleteEllipticF(real rex, real imx, real m_param,
real nbr_value,integer nbr_test),
im_incompleteEllipticF(real rex, real imx, real m_param,
real nbr_value,integer nbr_test)
Arguments:
rex
,imx
: real and imaginary parts of the complex argument.
Additional information on incompleteEllipticF
:
Have to beware branch points at +/- arcsin(1/sqrt(m)) + 2*pi*k,
so the nbr_value
input argument is for picking the
proper branch by continuity; if 0, then the principle branch
is picked. Branch values differ by 2*ellipticK(m).
nbr_test
is a boolean flag for whether to apply the
aforementioned continuity test.
Reference: Abramowitz and Stegun 17.4.11
Prerequisites: 2D soapfilm model with simply connected surface. Dirichlet_elastic energy defined using a named quantity, but no others, i.e. all facets given tension 0.
Usage: Remove all constraints and boundaries. Run to_disk or to_triangle. Then evolve.
Sample datafile: dirichlet_E.fe
Assumptions and features:
Usage: dxf >>> "filename.dxf"
Assumptions and features:
Usage: dxf_thick >>> "filename.dxf"
Usage: set torus mode view to
clipped, run
detorus,
then embox
.
WARNING: embox does not nicely handle facets that are exactly on the bounding box walls, so if there are any such facets, it is advised to move the surface BEFORE doing detorus, i.e.
clipped; set vertex x x+0.1; set vertex y y+0.1; set vertex z z+0.1; detorus; embox;
Assumptions:
There are five useful commands:
foamface_mark
: finds contiguous faces, and marks the facets of
each contiguous face with the same value of the
facet attribute fmark
, whose value value ranges
from 1 up to the number of full faces, which is kept in
the variable foamface_count
.
foamface_min
: finds the minimum area contiguous face. Runs
foamface_mark
itself, so you don't have to.
foamedge_mark
: finds contiguous triple edges, and marks the
edges of
each contiguous triple edge with the same values of the
edge attribute emark
, whose values
from 1 up to foamedge_count
.
foamedge_min
: finds the minimum length contiguous triple edge.
Runs foamedge_mark
itself, so you don't have to.
foam_signature
: finds number of polygons of each type on each body.
When done, the array body_poly_counts
holds number of faces
of given sides for each body. After foam_signature,
you can do
print body_poly_countsto see the results. For example, for twointor.fe, which has two bodies, the result is
{{0,0,0,6,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,6,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
Assumptions and features:
jvx_transparency
to the desired transparency, between 0 and 1, before running foamface_jvx
.
foamface_jvx >>> "filename.jvx"
x_sin_coeff
,
y_sin_coeff
,
z_sin_coeff
,
x_sin_coeff
,
y_sin_coeff
, and
z_sin_coeff
for your convenience.
Assumptions:
f_component(integer order)
Assumptions:
gaussequi
oldx
so the revert
command defined herein restores the original surface.
Assumptions:
gaussmap
Assumptions:
gaussequi(real maxarc)
maxarc
is the cutoff arclength for refinement, in radians.
Assumptions and features:
Usage: iges >>> "filename.igs"
Assumptions and features:
Usage: iges114 >>> "filename.igs"
Assumptions and features:
iges_double_sided
to 1, then it will do front and back
versions of each facet.
iges_edge_tubes
to 1, then each edge will be
displayed as a long thin tube..
Usage: iges128 >>> "filename.igs"
Assumptions and features:
Usage: iges144 >>> "filename.igs"
Assumptions and features:
intersect_eps
is the tolerance for being considered
equal to zero, i.e. for detecting parallel or border-intersecting facets.
Usage: detect
Output: prints ids of facets and edges that intersect.
Will not work in Lagrange model.
Assumptions and features:
Usage: jvx >>> "filename.jvx"
Assumptions and features:
Usage: maya >>> "filename.ma"
Note: The default length unit is cm, but if you want to use something
different, then set the maya_length_unit
variable to the appropriate string
after loading maya.cmd and before running the maya
command,
e.g.
maya_length_unit := "in" maya >>> "filename.ma"Valid length unit strings are: "mm", "millimeter", "cm", "centimeter", "m", "meter", "km", "kilometer", "in", "inch", "ft", "foot", "yd", "yard", "mi", "mile".
Note: To prevent names generated by this script from conflicting with
existing maya names or names from another datafile, there is a string variable
maya_name
that is prepended to all names generated by this script.
There is a maya namespace feature that probably could be used in place
of this, but I do not understand it yet. The maya_name
default is "AAA";
I didn't use the datafilename since this may contain illegal characters
and also would prevent generating multiple maya objects from the same datafile.
So if you are going to use multiple surfaces simultaneously, change
maya_name
before executing the maya command.
Assumptions and features:
Usage: maya1 >>> "filename.ma"
Note: The default length unit is cm, but if you want to use something
different, then set the maya_length_unit
variable to the appropriate string
after loading maya.cmd and before running the maya
command,
e.g.
maya_length_unit := "in" maya >>> "filename.ma"Valid length unit strings are: "mm", "millimeter", "cm", "centimeter", "m", "meter", "km", "kilometer", "in", "inch", "ft", "foot", "yd", "yard", "mi", "mile".
Note: To prevent names generated by this script from conflicting with
existing maya names or names from another datafile, there is a string variable
maya_name
that is prepended to all names generated by this script.
There is a maya namespace feature that probably could be used in place
of this, but I do not understand it yet. The maya_name
default is "AAA";
I didn't use the datafilename since this may contain illegal characters
and also would prevent generating multiple maya objects from the same datafile.
So if you are going to use multiple surfaces simultaneously, change
maya_name
before executing the maya command.
Contents:
neville1
- interpolation and derivatives in one dimension
neville2
- interpolation and derivatives in two dimensions.
neville1_data
should be set up by caller, redimensioning if necessary.
define neville1_data real[order+1][dim]; // fill in node data in neville1_data ... neville1(order,dim,u);where
u
is the value between 0 and 1 where the interpolation is desired.
The input array neville1_data is not modified. The interpolated values and
derivatives with respect to u
are returned in the one-dimensional arrays
neville1_value[dim]
and neville1_deriv[dim]
.
Usage of neville2:
The global array neville2_data
should be set up by caller, redimensioning if necessary.
define neville2_data real[order+1][order+1][dim]; // fill in node data in neville2_data ... // fille in the array nevill2_u[2] with the coordinates of the interpolation spot neville2_u[1] := 0.3; neville2_u[2] := 0.56; neville2(order,dim);The input array neville2_data is not modified. The interpolated values and partial derivatives with respect to
u
are returned in the one-dimensional array
neville1_value[dim]
and the two-dimensional array
neville1_deriv[dim][2]
.
Assumptions and features:
obj_double_sided
is set to 1, in which case each
facet will be drawn twice slightly apart.
obj_edge_flag
is set to 1 (which is the default value).
Edges are shown as 4-sided tubes. The relative size of the
tubes can be set with the variable tube_radius
, whose
default value is 0.002.
Usage:
show edge where ...
" and "show facet where ...
" commands.
obj_double_sided
to 1 if you want back sides of facets.
obj_edge_flag
to 0 if you want no edges shown.
obj
and redirect output to file, for exampleobj >>> "filename.obj"
Assumptions and limitations:
Usage: do_off >>> "filename.off"
cosine_cutoff
(default 0.8).
Adjacent facets with normals whose angle between them has cosine less
than the cutoff get separate vertices.
Assumptions and limitations:
Usage: offn >>> "filename.off"
Assumptions and limitations:
Usage: do_off >>> "filename.off"
order_number
, which the script creates
itself. It does not modify vertex or edge id numbers.
Assumptions:
order
id
numbering consecutive around a loop:
define vertex attribute vertex_order_key real; define edge attribute edge_order_key real; define facet attribute facet_order_key real; define body attribute body_order_key real; define facetedge attribute facetedge_order_key real; read "order.cmd"; renumber := { order; set vertex vertex_order_key order_number; set edge ee edge_order_key ee.vertex[1].vertex_order_key; set facetedge fe facetedge_order_key fe.edge[1].edge_order_key; set facet ff facet_order_key min(ff.vertex,vertex_order_key); set body bb body_order_key min(bb.facet,facet_order_key); reorder_storage; renumber_all; }
Assumptions and features:
percolate
- calculates clusters of facets, and numbers each
facet with a cluster number in the attribute "cluster_number".
slow_percolate
- slower, alternate algorithm for checking.
color_clusters
- colors facets according to cluster number (mod 16),
with internal cluster edges the same color as the cluster and
edges between clusters black.
state
attribute
of each edge to 0 for "off" or 1 for "on", for example
set edge state (random > 0.3)
.
percolate
or slow_percolate
.
color_clusters
to see the clusters. In the string model, you
should do "show facets where 1
" to see the facets.
Assumptions and features:
Usage:
show edges where ...
" and "show facets where ...
"
commands.
ply >>> "filename.ply"
Assumptions and features:
Usage: polyfilm >>> "filename.poly"
Assumptions and features:
Usage:
show edge where ...
" command to declare which
edges are to be depicted as thin cylinders.
edge_radius
to the desired radius of edge cylinders.
show facet where ...
" command to set which facets to do.
povray
and redirect to desired file, e.g. povray >>> "something.pov"
Assumptions and features:
Usage:
show edge where ...
" command to declare which
edges are to be depicted as thin cylinders.
edge_radius
to the desired radius of edge cylinders.
show facet where ...
" command to set which facets to do.
critcos
to the cosine of the critical angle
between normals for facets to be regarded as smoothly joined.
povray
and redirect to desired file, e.g. povray >>> "something.pov"
eboxes
and fboxes
for finding the bounding box for each facet or edge in
the quadratic model. This is useful since quadratic facets and edges
may extend beyond the vertices.
Assumptions and features:
fboxes
.
ebox
or facet fbox
array attributes. These have dimension [space_dimension][2], with
minimum being the first and maximum the second entry in each dimension.
fboxes
automatically calls eboxes
.
fboxes
Assumptions and features:
quadmeet
eboxes
and fboxes
for finding the bounding box for each facet or edge in
the quadratic torus model.
This is useful since quadratic facets and edges
may extend beyond the vertices.
The bounding box is calculated in terms
of normalized unit cell coordinates, i.e. the edge vectors of the
unit cell are the basis vectors for the normalized coordinates.
Assumptions and features:
fboxes
.
ebox
or facet fbox
array attributes. These have dimension [space_dimension][2], with
minimum being the first and maximum the second entry in each dimension.
fboxes
automatically calls eboxes
.
fboxes
This example reorders vertices in diagonal order, by their distance along the (1,1,1) direction. Other elements are reordered according to their vertices.
Usage: reorder
Usage: rewrap
rgb_values[16][4]
of Surface Evolver's color RGB values in array form.
Values are between 0 and 1. Fourth coordinate is alpha,
value always 1.
Assumptions and features:
Usage: rib >>> "filename.rib"
Usage: rotate(angle)
where angle is in radians.
Usage:
Enter command: read "save_view.cmd" Enter command: save_view >>> "something.view" ... Enter command: read "something.view"
Usage: show_equi
Usage: mark_simply_connected
slice_aa*x + slice_bb*y + slice_cc*z = slice_ddwhere
slice_aa
, slice_bb
, slice_cc
and
slice_dd
are global variables the user should set before
calling slice
.
Usage: slice
Output: prints the length of slice, and the area inside the slice.
Note all area inside slice is counted as positive! Try not to slice exactly through vertices!!
slice_aa*x + slice_bb*y + slice_cc*z = slice_ddwhere
slice_aa
, slice_bb
, slice_cc
and
slice_dd
are global variables the user should set before
calling slice
.
Usage: slice2(integer body_id)
Output: prints the length of slice, and the area inside the slice.
The length is saved in the global variable lensum
, and the
area is saved in areasum
.
Note all area inside slice is counted as positive! Try not to slice exactly through vertices!!
Commands included:
drawslice
- make new edges across facets along plane.
slicer
- make slice and dissolve all facets, edges, and vertices
on negative side of the plane. Calls drawslice
.
slice_a
,slice_b
,slice_c
,slice_d
variables so
slice_a*x + slice_b*y + slice_c*z >= slice_dis the side you want, and do
slicer
.
The default plane is slice_a
:= 0, slice_b
:= 0,
slice_c
:= 1, slice_d
:= .1
Output: truncated surface on positive side of the plane.
Try not to slice exactly through vertices!!
To mark the vertices and edges created by the current slicing,
there are a vertex attribute v_timestamp
and an edge attribute
e_timestamp
that are set to slice_timestamp
, which is incremented
each time slicer is called. This is to permit doing multiple slices in
various directions and being able to identify which vertices and which
edges are on which slice planes.
Works in the torus model by rewrapping wrapped edges that would be cut so unwrapped part is on positive side of cut plane.
Assumptions and features:
Usage: stl >>> "filename.stl"
Assumptions:
dupnum
.
Usage: dupnum := something; strdup >>> "filename.fe"
strips
- quick algorithm for coloring strips.
strips2
- slower algorithm that aims for longer strips
by trying multiple possibilities for strip directions from
starting triangle.
Usage: strips
Usage: strips2
tuber
also works in the torus model; a new body is created for all
the tube facets to be on, so they will display when "connected"
display mode is in effect. However, the tubes are displayed
independently of the other bodies, and tend to stick out in
various directions.
The edges to be tubed should have their intube
attribute set positive.
Usage: tuber(real tube_radius,integer tube_sides, integer tube_caps)
where
tube_radius
is the radius of the tubes,
tube_sides
is how many sides on each tube, at least 3, and
tube_caps
is 0 for no caps, 1 for cone caps.
Example:
set edge intube (on_constraint 1) tuber(0.01,6,0);
Usage:
unseam_mark
to nonzero for those
edges you want to be split.
unseam
NOTE: unshear
needs to change the torus periods, but can't directly
since torus_periods
is a read-only array (because it is remembered
as a formula). So the assumption is that the shear entries of the
torus_periods
array are variables of particular names, shearij
for
torus_periods[i][j]
. (remember indexing starts with 1)
Usage: unshear
Assumptions and features:
Usage:
show edge where ...
" to show desired edges.
vrml
and re-direct output to file, e.g. Enter command: vrml >>> "myfile.wrl";
Assumptions and features:
Usage:
show edge where ...
" to show desired edges.
vrml2
and re-direct output to file, e.g. Enter command: vrml2 >>> "myfile.wrl";
wavefront
- Produces wavefront file without normals.
wavefrontn
- Produces wavefront file with normals.
Assumptions and features:
Usage:
show facet where ...
" to show desired facets.
wavefront >>> "filename.obj"
spread
to the relative size of the border (default 0.2)
wetfoam
with output redirected to desired file, e.g.
Enter command: wetfoam >>> "wetfile.fe"
border_body
.
This file replaces wetfoam.cmd
, which is now obsolete.
Assumptions and features:
x3d
and re-direct output to file, e.g.
Enter command: x3d >>> "myfile.x3d";
Usage:
xgridsize
and ygridsize
to the desired resolution,
i.e. pixels across and down.
xray >>> "filename.ps"
xray
command will calculate the bounding box of the surface itself.
Works in torus or non-torus mode. In torus mode, everything will
automatically be wrapped back to the unit cell, so you don't have
to worry about that.
Usage:
color1
and color2
to the two colors you want, if the
default black and white are not suitable.
zebra