Mandala Paper Model Project / Atsuro Seto 2002 - 2003

Completed Paper Model of Guhyasamaja and the several mockups for it
Atsuro Seto

For folding / unfolding paper model simulation in Lightwave 7.5.
Problem is different Pivots handling of modeler and layout.
Pivots in Modeler cannot rotate anyway. Pivot has no rotation info there.
Also Pivot in Layout is nothing but a protractor, which does not rule Rotation but
the Rotate tool measures own angle from Pivot angle, To me,
multi-layered objects and their pivots cause big mess.
("Rec Pivot Rot" command does nothing but oddly twisted by actual Rotation).
As I couldn't disentangle those profound twists,
Rather, I prefer give certain counter-twist on each layer conciously beforehand.

So I made a set of scripts, one for Modeler, another for Layout.
In version 1, to hand some params from Modeler to Layout, I used Powergons
but that's not smart. Then I shifted my mind from Powergon to orthodox
writing / reading text file tech. Yes that's much better.

Newer version(Ver1.1) are as follows:
Anyway you shouldn't apply these scripts onto your one and only original file but on your copy test dummies.

//Hinge (Ver1.1)

// Select clock-wise 3 points of a polygon in 1st layer.
// Do this Hinge script.
// (First time, You may be asked where you prefer a new parameters text to be saved? usually
// this can be current object dir or Temp dir. this file will be back to HingLayout script later).

// the 1st point becomes this layer's pivot, the 2nd point alligns with the 1st point along z axis.
// 3rd point comes in x>0 quadrants. and these 3 points polygon faces toward y plus direction.
// Select all other polygons and move them to next layer. Mark the last layer as "Background layer".

// Now select clock-wise 3 points again and Do this Hinge script again. And so on.


@version 2.3
@script modeler
@name Hinge

var pnt_cnt;
var p1,p2,p3,d1,d2;
var cx, cy, cz, cc;//normal
var rotx=roty=rotz=0;//rotx,roty,rotz;
var idPnt, idPoly;
var blOtherWise=false;


pnt_cnt = pointcount();

if(pnt_cnt != 3){
error("Select 3 points. <br>1)st as Heading-axis: Y 2)nd as Bend-axis: Z. 3)rd Bend into x=>0 quadrants");

p1 = pointinfo( points[1] ); // first point becomes pivot
p2 = pointinfo( points[2] ); // 2nd point in clockwise order
p3 = pointinfo( points[3] ); // 3rd hinge hundle //info(p1, p2, p3);

selpoint( CLEAR );
var fg=lyrfg(); //info(fg[1]);
var bg=lyrbg();

if((objPath = getfile("Save as working file","_work.lwo",getdir("Objects"),false))==nil) return;
if(fileexists(objPath))base = split(objPath);
// splitted into 1 to 4 in an array:drive, path, filename, and extension
tmpPath = getdir("Temp") + "\\" + base[3] + ".txt";//
if ((tmpfile=File(tmpPath, "w"))==nil)return;//info(tmpPath);
tmpPath = getdir("Temp") + "\\" + Mesh(0).name + ".txt";
if ((tmpfile=File(tmpPath, "a"))==nil)return;//info(tmpPath);
info("Temp: ",tmpPath);

d1 = < p2.x - p1.x , p2.y - p1.y , p2.z - p1.z >;// point to point distance
d2 = < p3.x - p1.x , p3.y - p1.y , p3.z - p1.z >;// info("d1: ", d1, "; d2: ", d2);

//if(d1.x!=0) info(rad(atan( d1.z / d1.x ))); else info(rad(90));

// get normal vector for future implementation.
cz = d1.x*d2.y-d2.z*d1.y; cy = d1.z*d2.x-d2.z*d1.x; cx = d1.y*d2.z-d2.y*d1.z;
//info ("cx: ", cx, ", cy: ", cy, ", cz: ", cz);
cc = sqrt(cx*cx+cy*cy+cz*cz); cx=cx/cc; cy=cy/cc; cz=cz/cc; // normalized unit of the surface
//info ("cx: ", cx, ", cy: ", cy, ", cz: ", cz);

roty=deg(acos(d1.x/sqrt(d1.x*d1.x+d1.z*d1.z)));// info(roty);
if (d1.z<0) roty=360-roty;
roty=90-roty;// info(roty);//turn ccw 90 about +y axis. (start angle 0 is on +x axis).
rotate( roty , Y, p1);
roty = rad(roty); //info("roty_rad = ", roty);

d1 = < d1.x*cos(roty)-d1.z*sin(roty), d1.y , d1.x*sin(roty)+d1.z*cos(roty) >;
d2 = < d2.x*cos(roty)-d2.z*sin(roty), d2.y , d2.x*sin(roty)+d2.z*cos(roty) >;
if (d1.y<0) rotx=360-rotx;
rotate( rotx , X, p1);
rotx = rad(rotx); //info("rotx_rad = ", rotx);
d1 = < d1.x , d1.z*sin(rotx)+d1.y*cos(rotx) , d1.z*cos(rotx)-d1.y*sin(rotx) >;
d2 = < d2.x , d2.z*sin(rotx)+d2.y*cos(rotx) , d2.z*cos(rotx)-d2.y*sin(rotx) >;
//info("d1: ", d1, "; d2: ", d2); //
rotz=deg(acos(d2.y/sqrt(d2.y*d2.y+d2.x*d2.x))); //info(rotz);
if (d2.x<0) rotz=360-rotz;
rotate( rotz , Z, p1);
//rotz = rad(rotz); info("rotz_rad = ", rotz);
roty = deg(roty);
rotx = deg(rotx);
//rotz = deg(rotz); info("rotz_deg = ", rotz);


else tmpfile.writeln("none");
tmpfile.writeln(roty, " 0 0");
tmpfile.writeln(roty, " ", rotx, " ", rotz);


//HingeLayout (Ver1.1)
@version 2.3
@script generic
@name HingeLayout

mesh = getfirstitem(MESH);
tmpPath=getdir("Temp") + "\\" + strArray[1] + ".txt";
if ((tmpfile=File(tmpPath, "r"))==nil){
if((tmpPath = getfile("Open parameters file","*.txt",tmpDir,true))==nil) return;
if ((tmpfile=File(tmpPath, "r"))==nil) return;
lineCount = tmpfile.linecount();
var array2[lineCount/4][3];
scene = Scene();
if(scene.generalopts[3]==true) ParentInPlace();
for(i=1; i<=lineCount/4; i++){
CreateKey (0);

Rotation (rotUnfold.x, rotUnfold.y, rotUnfold.z);
CreateKey (0);
Rotation (rotFold.x, rotFold.y, rotFold.z);
CreateKey (2);;

if(scene.generalopts[3]==false) ParentInPlace();

info("",s," Objects converted.");


The above scripts were specifically for my own comfort I had been tired
with twisted riddles of Deeply parented Bonessss and Rec Pivot Rot,
and Pivot Rotation seems no effect to change zero-rotation of Layered objects.....
You may say, usual Skelegons/BoneWeight treatment seems much better.
much easier especially if you only need to apply few, two three hinges
like doors, rudders. However in my case, to animate folding / unfolding
and assembling tens, some hundreds of paper parts, I needed these scripts.

To me, a real problem is that there's no way to pass such simple
parameters like pivot rotation, skelegon HPB etc directly apparently,
from modeller to layout. I wish it could be much more seamless.

In addition, Here I put two Keys: everything flat at Keyframe 1
then All-Folded,-modelled pos in keyframe 60.
And I didn't push the Rec Pivot Rot button in my "Layered hinges" treatment at all.
As a result, I could concentrate on goodly oriented Rotation HPB Rings only.

Thanks friends.

Completed Paper Model of Guhyasamaja and the several mockups for it
Atsuro Seto

dxf2x3d.exe version 1.1
version 2.1

Windows console and dialog exe

Convert dxf to x3d format.
Convert dxf to vrml format.

Tested with:
Flux Studio version 2.0
Cortona VRML Client version 5.1

Handling only 3DFACE, code 62, color indices 0 to 255, 10,20,30 xyz coords, vert 0 to 3, a pair of tri.
each index color is editable in cfg file. contains exe and cfg and a sample dxf. almost same.

First version developed in 1999.
Since then, totally forgot about them for long time.
One week ago i just found x3d format had already come.
So I am gonna update a bit.


Lingaraja Yaksi

3d-sketch by me
in LightWave.
This scene was
generated with
then rendered
in pov-ray.

dxf2pov.exe version 1.2

Windows commandline exe. Convert dxf to pov, inc formats.

Tested with:
Few DXF files exported from LightWave through my lscript.
Then rendered in POV-Ray 3.6x and 3.7x


If you are familiar with console commands, then open a console in the very this zip-expanded directory
in which, dxf2pov.exe and a sample foo.dxf reside, there type as follows, and hit Enter.

dxf2pov foo

Or you may prefer drag and drop your dxf file from somewhere to the dxf2pov.exe whitish icon body.

Anyway as the results, 3 files should come: foo.pov,, and foo.ini
Here in this case, "" is the main object file listed vertices/coords information extracted from DXF.
And others are render related, so called .pov scene file to include the inc files as many as you want
and .ini as initialization file to initialize or modify the render environments with several arguments..
Do double-click "foo.pov" and coming POV-Ray application inside, you can choose "foo.ini" to select
render size, still or animation, etc.

Version 1.2 - 23/MAR./07 From this version, DXF Index Colors (0To255) can be converted into rgb <0To1, 0To1, 0To1> format
Version 1.1 - 13/MAR./07
Version 1.0 - 26/FEB./99

dxf2pov.exe DXF to POV-Ray file Converter Written By Atsuro Seto
(c)1999-2007 All Rights Reserved. Atsuro Seto <>

Vajra Yogini (C) Atsuro Seto contains dxf2pov.exe, idx2col.dll, C-Sources.


@version 2.6
@name sel_Multi_Parts
@name sel_Multi_Surfaces

LightWave Modeler Script

Select multiple Parts at once.
Select multiple Surfaces at once.

7.5x and 9.0 trial
These scripts save the current LWO file in "as is" condition to know the binary info.
(Assuming TAGS chunk in the LWO2 binary contains COLR, PART, and SURF sub chunks Only).
The process itself will do No harm on your data.
but I say, am NOT Responsible for any happening, any damage, according to usage.

GREP search field on the bottom, you can try entering very strange string
to mark multiple parts/surfaces in the list. contains two scripts and this readme.

Ver. 0.69 (JAN 2007)
Uploaded 1st time

Ver. 0.6969 (FEB 2007)
Added Same Surface script.
Made the Scripts more simple and plain to avoid freezing, blaming.

Ver. 0.696969 (mid FEB 2007)
Changed a bit Part script only.
Last one couldn't prepare Parts array if Part1 had the same name with the Surface1.

And Here I abandoned my stupid version control.



@version 2.6

LightWave Modeler Script

Import DXF into LightWave with Converting its Index Colors to LightWave's Diffuse RGB.
and Convert LightWave's Diffuse RGB vector to DXF's Index Color 0 To 255. thus DXF Comes and Goes.

Export/Import from/to 7.5x, 9.0 trial

Import to good but cold-slept my fav. LightScape3.1,
Also Import into POV-Ray through dxf2pov.exe.

These scripts are just for my own purpose, for debugging dxf2pov utility.
I don't have and I won't test with AutoCAD.
Many DXF codes and values are skipped and ignored.
but 3DFACEs and their Index Colors can be cared.
According to Keith Rule's "3D Graphics File Formats",
My implementation seems not so wrong. But not so much sensitively precise.
As always, I say, am NOT Responsible for any happening, any damage,

Create an object. Assign some Surfaces in LightWave.
Run the and save as anyname.dxf.
Then Run another to reload the same dxf into LightWave.
Check the Surface/Index Color correspondence.
Drop a mail on me. "it works. I'd like to correspond."

Women are welcome.

Ver. .69 - 28/MAR.2007

: AutoHotKey Script
; LightWave Modeler/Layout Run last LScript with F5 single hit.
If WinExist("LightWave") or WinExist("Layout") or WinExist("Modeler")
IfWinActive, ahk_class WMgrBasic
;Send F5
WinWaitActive, LScript, ,
Sleep, 100
MouseClick, left, 508, 342 ; (N) File Name pull down list.
Send {DOWN}
; MouseClick, left, 508, 360 ; select the first item(the latest in open history item)

I am not responsible for any happening, any damage, according to usage.
Use freely, But do not use on profit or pay me any.

This html revised on 29th/Sep./2010