/*
*/
import java.awt.font.*;
import java.awt.geom.*;
showInfoWindow() {
warning = new BTextArea("This is an experimental tool. In particular, it doesn't work\n"+
"well with some fonts."+
"However, it works often and can be useful, and that is my intention. \n"+
"But be aware that I can't be held responsible for any damage it does to \n"+
"your work.\n"+
"In case of crash, I suggest saving your work if it wasn't and closing Art of "+
"Illusion and opening it again.\n\n"+
"Enjoy!", 10, 80);
warning.setEditable(false);
wrnDlg = new PanelDialog(window, "Important Information", new BScrollPane(warning));
}
showHelpWindow() {
helpText = new BTextArea("Text tool script.\n\n"+
"By Yokiyoki (Julio Sangrador-Pat�n), with great aid from Peter Eastman and others.\n"+
"This is a beta version, but quite usable especially on windows.\n\n"+
"Help:\n\n"+
"Tool to build the model of a string of text, in the form of simple approximating curves, tubes which follow these,\n\n"+
"flat triangle meshes or extruded solid triangle meshes. Steps:\n\n"+
"1. Choose one of the above at the top of the dialog.\n"+
"2. Choose a font face from the list. Be aware that (on linux at least) a great deal of them\n"+
"make the script crash. It seems to have to do with the font being Adobe type, but I'm not\n"+
"sure yet.\n"+
"3. Mark if you want it bold and/or italic.\n"+
"4. Write the text you want to be modelled.\n"+
"5. Enter the tolerance value, which grosso modo tells how accurate the outlines will be (the smaller\n"+
"the value, the more accurate).\n"+
"6. Enter the thickness of the mesh (for 3D meshes) or of the tube (for tubes). Useless for curves and flat surfaces.\n"+
"7. Enter the degree of subdivision you want for the meshes, which can be 0 or a positive integer. A value\n"+
"of at least 1 is recomended to avoid artifacts. You will seldom need more than 2, and might do well\n"+
"with 0.", 10, 80);
helpText.setEditable(false);
hlpDlg = new PanelDialog(window, "Help", new BScrollPane(helpText));
}
/* Modes */
M_TUBE = -1;
M_SPLINE = 0;
M_2D = 1;
M_3D = 2;
/* Prepare to remember the user selections */
if(global.textToolwantsBold == void) {
global.textToolwantsBold = false;
global.textToolwantsItalic = false;
global.textToolfont = "SurelyThisIsntAFontName";
global.textTooltheString = "Write some text";
global.textTooltolerance = 0.1;
global.textToolmesh = M_2D;
global.textToolthickness = 0.1;
global.textToolsubdivideTimes = 1;
}
/* error message function */
errorMessage(s) {
return (new MessageDialog(window, s)).getChoice();
}
/* Rewrite of the solidify function, using the static methods of the Extrude Dialog Plugin */
/* Copied from a message to the forum by Peter Eastman */
solidify2(info, thickness) {
extrudeDialog = ModellingApp.getClass("artofillusion.tools.ExtrudeDialog");
extrudeMesh = extrudeDialog.getMethod("extrudeMesh",
new Class [] {TriangleMesh.class, CoordinateSystem.class, Vec3.class, Integer.TYPE,
Double.TYPE, Boolean.TYPE});
extruded = extrudeMesh.invoke(null, new Object[] {info.object, info.coords,
new Vec3(0,0,thickness), 1, 0.0, true});
return extruded;
}
/* Create the components of the options dialog */
meshType = new RadioButtonGroup();
meshSpline = new BRadioButton("Silhouette", global.textToolmesh==M_SPLINE,meshType);
mesh2D = new BRadioButton("2D surface", global.textToolmesh==M_2D,meshType);
mesh3D = new BRadioButton("3D solid", global.textToolmesh==M_3D,meshType);
meshTube = new BRadioButton("Tube", global.textToolmesh==M_TUBE,meshType);
kindOfMesh = new GridContainer(2, 2);
kindOfMesh.setDefaultLayout(new LayoutInfo(LayoutInfo.WEST, LayoutInfo.NONE, new Insets(2, 2, 2, 2), null));
kindOfMesh.add(meshSpline, 0, 0);
kindOfMesh.add(mesh2D, 0, 1);
kindOfMesh.add(mesh3D, 1, 0);
kindOfMesh.add(meshTube, 1, 1);
fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
fontsList = new BList(fonts);
fontsList.setPreferredVisibleRows(10);
fontsList.setMultipleSelectionEnabled(false);
theSelectedIndex = 0;
for(y=0;yM_SPLINE) { // i.e, Surface or Solid
// try to triangulate the curve
theMesh = theCurve.subdivideCurve(subdivideTimes).convertToTriangleMesh(tolerance);
if (theMesh == null)
continue;
currentGlyphOI = new ObjectInfo(theMesh, new CoordinateSystem(), glyphName);
currentGlyphOI.setTexture(sceneDefaultTex, sceneDefaultTex.getDefaultMapping());
if(firstCurveOfGlyph) {
fullLetterOI = currentGlyphOI;
}
else { // More curves, see if they intersect or unite what we already have
meshToTestForIntersection = new ObjectInfo(solidify2(currentGlyphOI,0.2), currentGlyphOI.coords.duplicate(), glyphName);
meshToTestForIntersection.setTexture(sceneDefaultTex, sceneDefaultTex.getDefaultMapping()); // for getBounds() to work
coordsDiff = currentGlyphOI.getBounds().getCenter().minus(meshToTestForIntersection.getBounds().getCenter());
meshToTestForIntersection.coords.setOrigin(meshToTestForIntersection.coords.getOrigin().plus(coordsDiff));
testCSG = new CSGObject(fullLetterOI,meshToTestForIntersection,CSGObject.INTERSECTION);
testCSGMesh = testCSG.convertToTriangleMesh(tolerance);
if(testCSGMesh.getEdges().length > 0) { // Intersects
bounds1 = fullLetterOI.getBounds();
bounds2 = currentGlyphOI.getBounds();
firstIsLarger = ((bounds1.maxx-bounds1.minx)*(bounds1.maxy-bounds1.miny) >= (bounds2.maxx-bounds2.minx)*(bounds2.maxy-bounds2.miny));
firstMesh = (firstIsLarger ? fullLetterOI : currentGlyphOI);
secondMesh = (firstIsLarger ? currentGlyphOI : fullLetterOI);
meshToCut = new ObjectInfo(solidify2(secondMesh,0.2), secondMesh.coords.duplicate(), glyphName);
meshToCut.setTexture(sceneDefaultTex, sceneDefaultTex.getDefaultMapping()); // for getBounds() to work
coordsDiff = secondMesh.getBounds().getCenter().minus(meshToCut.getBounds().getCenter());
meshToCut.coords.setOrigin(meshToCut.coords.getOrigin().plus(coordsDiff));
aCSG = new CSGObject(firstMesh, meshToCut, CSGObject.DIFFERENCE12);
aCSGMesh = aCSG.convertToTriangleMesh(tolerance);
fullLetterOI = new ObjectInfo(aCSGMesh,fullLetterOI.coords.duplicate(), glyphName);
fullLetterOI.setTexture(sceneDefaultTex, sceneDefaultTex.getDefaultMapping());
}
else { // Unites
aCSG = new CSGObject(fullLetterOI, currentGlyphOI, CSGObject.UNION);
aCSGMesh = aCSG.convertToTriangleMesh(tolerance);
fullLetterOI = new ObjectInfo(aCSGMesh,fullLetterOI.coords.duplicate(), glyphName);
fullLetterOI.setTexture(sceneDefaultTex, sceneDefaultTex.getDefaultMapping());
}
try { // Optimize the mesh while we are building it
fullLetterOI.object = TriangleMesh.optimizeMesh(fullLetterOI.object);
fullLetterOI.clearCachedMeshes();
} catch (Exception e) {e.printStackTrace();} // Should we act? Not sure...
}
firstCurveOfGlyph = false;
}
else if(mesh==M_TUBE) { // User wants tubes
nVerts = theCurve.getVertices().length;
tubeThickness = new double[nVerts];
for(t=0;t