Hello everyone
I have been trying for two days to make the example of Mr. SCARPINO, which I found in the book, Automatic Sketchup, but every time I try, it sends me errors, yet I have not changed anything. have a copy paste directly in ruby code editor, the goal of my work is to understand how ruby, javascript and html are linked to be able to do a simple test, create a form with a text box, in which I type a text or a number that will be displayed in a UI.messagebox by pressing a button to validate
create_face ='<html>
<head>
<script type="text/javascript">
function sendPoints()
{
var ids = new Array ("x1", "y1", "z1", "x2", "y2", "z2","x3", "y3", "z3", "x4", "y4","z4");
var arg = "" ; var entry = "" ; var valid = true ;
// Iterate through the text boxes to form output argument
for (i in ids)
{
entry = document.getElementById(ids[i]).value
if ((entry.length == 0) || isNaN(entry))
{
valid = false ;
}
else
{
arg = arg + entry + ",";
}
}
// Send argument to SketchUp script for processing
if (!valid)
{
arg = "" ;
}
window.location = 'skp:create_face@' + arg;
}
</script>
</head>
<body>
<!-- Location of the first vertex -->
Point 1:
<input type="text" id="x1" value="0.0" size="10" maxlength="6"/>
<input type="text" id="y1" value="0.0" size="10" maxlength="6"/>
<input type="text" id="z1" value="0.0" size="10" maxlength="6"/>
<br /><br />
<!-- Location of the second vertex -->
Point 2:
<input type="text" id="x2" value="10.0" size="10" maxlength="6"/>
<input type="text" id="y2" value="0.0" size="10" maxlength="6"/>
<input type="text" id="z2" value="0.0" size="10" maxlength="6"/>
<br /><br /> <!-- Location of the third vertex -->
Point 3:
<input type="text" id="x3" value="10.0" size="10" maxlength="6"/>
<input type="text" id="y3" value="10.0" size="10" maxlength="6"/>
<input type="text" id="z3" value="0.0" size="10" maxlength="6"/>
<br /><br />
<!-- Location of the fourth vertex -->
Point 4:
<input type="text" id="x4" value="0.0" size="10" maxlength="6"/>
<input type="text" id="y4" value="10.0" size="10" maxlength="6"/>
<input type="text" id="z4" value="0.0" size="10" maxlength="6"/>
<br /><br />
<!-- Send points to JavaScript -->
<input type="submit" onclick="sendPoints();"value="Create Face" />
</body>
</html>'
face_dialog.add_action_callback("create_face") {|d, arg|
if arg.to_s.length == 0
puts "Invalid input. Coordinates must be valid numbers."
else v = arg.to_s.split(",")
pt1 = Geom::Point3d.new(Float(v[0].strip), Float(v[1].strip),Float(v[2].strip))
pt2 = Geom::Point3d.new(Float(v[3].strip), Float(v[4].strip),Float(v[5].strip))
pt3 = Geom::Point3d.new(Float(v[6].strip), Float(v[7].strip),Float(v[8].strip))
pt4 = Geom::Point3d.new(Float(v[9].strip), Float(v[10].strip),Float(v[11].strip)) vec1 = pt2 - pt1
vec2 = pt2 - pt3
plane = [pt1, vec1 * vec2]
if pt4.on_plane? plane
Sketchup.active_model.entities.add_face pt1, pt2, pt3, pt4
else
puts "Invalid input. Points must lie on the same plane."
end
end
}
face_dialog= UI::WebDialog.new("face_dialog")
# Display the dialog box
if RUBY_PLATFORM.index "drawin"
face_dialog.show_modal
else
face_dialog.show
end
although very good, Mat’s book is also very old, and some things in both SU and Ruby have changed…
One thing to be careful of is copy pasting directly from the PDF as it will contain formatting that can easily break the snippets…
this is partly why the code isn’t working for you…
if you format the snippets first it is easier to follow…
create_face ='<html>
....
</html>'
face_dialog= UI::WebDialog.new("face_dialog")
##############################################
## you have to SET the html you want to use
face_dialog.set_html(create_face)
##############################################
face_dialog.add_action_callback("create_face") {|d, arg|
if arg.to_s.length == 0
puts "Invalid input. Coordinates must be valid numbers."
else v = arg.to_s.split(",")
pt1 = Geom::Point3d.new(Float(v[0].strip), Float(v[1].strip),Float(v[2].strip))
pt2 = Geom::Point3d.new(Float(v[3].strip), Float(v[4].strip),Float(v[5].strip))
pt3 = Geom::Point3d.new(Float(v[6].strip), Float(v[7].strip),Float(v[8].strip))
pt4 = Geom::Point3d.new(Float(v[9].strip), Float(v[10].strip),Float(v[11].strip))
##################################################
# vec1 was on the end of 'pt4 =' line above, breaking the code...
vec1 = pt2 - pt1
##################################################
vec2 = pt2 - pt3
plane = [pt1, vec1 * vec2]
if pt4.on_plane? plane
Sketchup.active_model.entities.add_face pt1, pt2, pt3, pt4
else
puts "Invalid input. Points must lie on the same plane."
end
end
}
# Display the dialog box
if RUBY_PLATFORM.index "drawin"
face_dialog.show_modal
else
face_dialog.show
end
Good morning, John
thank you very much for the clarifications that you brought, it is true that the bookin of Matt is old but I find it is good to start and to learn with examples, concerning the example which I quoted, I have checked line by line to see where it does not work, the html part no worries on it, the sketchup part when I remove some line, no error and it works in part, but no interaction with html page, the two lines are:
the first : window.location = 'skp:create_face@' + arg;
the second :```if RUBY_PLATFORM.index “drawin”
face_dialog.show_modal
else
face_dialog.show
if RUBY_PLATFORM.index “drawin”
face_dialog.show_modal
else
face_dialog.show
end
I fixed it so that it works, and wrote comments where I changed it…
##################################################
# vec1 was on the end of 'pt4 =' line above, breaking the code...
vec1 = pt2 - pt1
##################################################
##############################################
## you have to SET the html you want to use
face_dialog.set_html(create_face)
##############################################
Just following along … a newbie myself and just spend 5 days figuring out my own issue. Following an older tutorial for 2D game in Ruby and just digging in hard to get it to run. I figured out what cause`s a uninitialized constant (Name Error). Stick with it and at least with Rudy scripts for SketchUp. You have a good forum to look to. I just got lucky and commented out what I thought needed to be included.
Feel like a blind man looking for the corner of a round room …Peace
#↓ 0 spaces ↓r This branch will only detect macOS if it's correctly written. If you don't use macOS you would have never found that there is something wrong.
if RUBY_PLATFORM.index "darwin"
face_dialog.show_modal
#↑ 2 spaces
else
Take a look at a Ruby style guide. Try to develop an attention for detail. You should not aim to get your code “working” but also that it is structured and easily readable. Then mistakes will catch your eye and you can avoid them. Most beginners’ mistakes happen because people don’t see them.
In addition to @Aerilius’ recommendation, if you use a good code editor, its highlighting and indentation will reveal many syntax errors as it can’t make sense of the same things the interpreter can’t parse.
thank you for every body
but i tried the code posted by john, and always the same thing,
this is the report error that i looked on ruby console : “Nil result (no result returned or run failed)”
Error: #<SyntaxError: :26: syntax error, unexpected tIDENTIFIER, expecting end-of-input
window.location = ‘skp:create_face@’ + arg;
^>
C:/Users/LOUZA/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/as_rubyeditor/as_rubyeditor.rb:324:in eval' C:/Users/LOUZA/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/as_rubyeditor/as_rubyeditor.rb:324:in block in initialize’
SketchUp:1:in `call’
In typography (and book publishing) there exist many similar-looking characters with specific meanings in written texts. But programming languages do not use typography and are very sensitive that you use the only valid character. If you copy code from a book and the publisher has not properly disabled typography for code blocks, you get ‘…’ which is not the same as '…'.
This would have become obvious if you had formatted the code in the forum post with `.
The second problem is that the variable create_face is a string delimited with single quotes which contains another nested string wrapped in single quotes. So it is ambiguous where the outer string ends! After window.location = ' or after </html>' ? Therefore, the type of quotes that delimit a string must be escaped when they also occur within the string, using the escape character \:
Besides single-quoted '…' and double-quoted "…" strings, Ruby has a third way of defining strings which is much better for long strings like HTML documents:
<<-HEREDOC
No escaping of single quotes ' and double quotes " needed!
HEREDOC
The fact that the forum’s code highlighter paints the whole html string with all the colors of the rainbow should make you skeptical because a string is one single token and is usually highlighted with a single color. Therefore use a code editor with code highlighting.
thanks Aerilius
the blocking is finished on the window.location … and the window html opens normally, except that, even by entering values the face is not created after validation, i try to make a UI.messagebox in each line, to see where they block, but the ruby code don"t receive informations
the mistake was mixing the html form names, the terminology in general, and the accents and quotation marks in the sentence ; window.location …
thank you john and thanks for every body
another example by changing the webdialog by htmldialog the code no longer works, and the html page is not displayed, so is there anyone who can inform me the top …
dlg_html ='<html>
<head>
<script type="text/javascript">
function sendPoints()
{
var ids = new Array ("x1", "x2", "x3" );
var arg = "" ; var entry = "" ; var valid = true ;
// Iterate through the text boxes to form output argument
for (i in ids)
{
entry = document.getElementById(ids[i]).value
if ((entry.length == 0) || isNaN(entry))
{
valid = false ;
}
else
{
arg = arg + entry + ",";
}
}
// Send argument to SketchUp script for processing
if (!valid)
{
arg = "" ;
}
window.location = \'skp:dlg_html@\' + arg ;
}
</script>
</head>
<body>
<!-- Location of the first vertex -->
Point 1:
<input type="text" id="x1" value="0.0" size="10" maxlength="6"/>
<input type="text" id="x2" value="10.0" size="10" maxlength="6"/>
<input type="text" id="x3" value="10.0" size="10" maxlength="6"/>
<br /><br />
<!-- Send points to JavaScript -->
<input type="submit" onclick="sendPoints();"value="Create Point" />
</body>
</html>'
point_dialog = UI::HtmlDialog.new("dlg_html")
point_dialog.set_html(dlg_html)
point_dialog.add_action_callback("dlg_html") {|d, arg|
arr= arg.to_s
UI.messagebox(arr)
}
# Display the dialog box
if RUBY_PLATFORM.index "drawin"
point_dialog.show_modal
else
point_dialog.show
end