Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the predicate global focus (that is, the “rule applied” or the “current shape”)
# File lib/interfaces/custom.rb, line 204 204: def create_GUI_dialog_focus(predicate_type, class_name) 205: gui_dialog_focus = UI::WebDialog.new("Choose #{predicate_type} focus", true, "Choose #{predicate_type} focus", 250, 150, 150, 150, true) 206: 207: # Attach an action callback for getting the chosen focus 208: gui_dialog_focus.add_action_callback("get_focus") do |web_dialog, focus| 209: 210: gui_dialog_focus.close 211: 212: if focus == "RULE APPLIED" 213: # Find and show our html file 214: html_path = Sketchup.find_support_file "GUIDialogRuleFocus.html" , Constants::HTML_DIR 215: gui_dialog_rule = create_GUI_dialog_rule(predicate_type, class_name) 216: gui_dialog_rule.set_file(html_path) 217: gui_dialog_rule.show() 218: elsif focus == "CURRENT SHAPE" 219: # Find and show our html file 220: html_path = Sketchup.find_support_file "GUIDialogShapeFocus.html" , Constants::HTML_DIR 221: gui_dialog_shape = create_GUI_dialog_shape(predicate_type, class_name) 222: gui_dialog_shape.set_file(html_path) 223: gui_dialog_shape.show() 224: end 225: 226: end 227: 228: return gui_dialog_focus 229: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the number of points of the shape
# File lib/interfaces/custom.rb, line 733 733: def create_GUI_dialog_number_of_points(predicate_type, class_name) 734: gui_dialog_number_of_points = UI::WebDialog.new("Configure points number #{predicate_type}", true, "Configure points number #{predicate_type}", 700, 100, 150, 150, true) 735: 736: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 737: gui_dialog_number_of_points.add_action_callback("get_data") do |web_dialog, data| 738: 739: gui_dialog_number_of_points.close 740: data_a = data.split(",") 741: 742: point_type = data_a[0] 743: relation_type = data_a[1] 744: argument_type = data_a[2] 745: number = data_a[3] 746: argument_point_type = data_a[4] 747: 748: code = "labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{point_type}\") 749: number = 0 750: labels.each { |list| 751: number += list.size 752: }" 753: 754: case argument_type 755: when "NUMBER" 756: code = "#{code} 757: argument_number = #{number}" 758: when "CURRENT SHAPE" 759: code = "#{code} 760: labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{argument_type }\") 761: argument_number = 0 762: labels.each { |list| 763: argument_number += list.size 764: }" 765: when "PREVIOUS SHAPE" 766: code = "#{code} 767: labels = ShadeUtils.get_labels(ShadeUtils.previous_shape, \"#{argument_type }\") 768: argument_number = 0 769: labels.each { |list| 770: argument_number += list.size 771: }" 772: end 773: 774: predicate_string = "" 775: 776: case relation_type 777: when "EQUAL" 778: predicate_string = "(number == argument_number)" 779: when "DIFFERENT" 780: predicate_string = "!(number == argument_number)" 781: when "BIGGER" 782: predicate_string = "(number > argument_number)" 783: when "LESS" 784: predicate_string = "(number < argument_number)" 785: when "BIGGEREQ" 786: predicate_string = "(number >= argument_number)" 787: when "LESSEQ" 788: predicate_string = "(number <= argument_number)" 789: end 790: 791: code = "#{code} 792: result = #{predicate_string}" 793: 794: create_code(predicate_type, class_name, code) 795: end 796: 797: return gui_dialog_number_of_points 798: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the points focus (that is, the “number of points” or the “position of points”)
# File lib/interfaces/custom.rb, line 316 316: def create_GUI_dialog_points_focus(predicate_type, class_name) 317: gui_dialog_points_focus = UI::WebDialog.new("Choose #{predicate_type} points focus", true, "Choose #{predicate_type} points focus", 250, 150, 150, 150, true) 318: 319: # Attach an action callback for getting the chosen points focus 320: gui_dialog_points_focus.add_action_callback("get_focus") do |web_dialog, focus| 321: 322: gui_dialog_points_focus.close 323: 324: if focus == "NUMBER OF POINTS" 325: # Find and show our html file 326: html_path = Sketchup.find_support_file "GUIDialogNumberOfPoints.html" ,Constants::HTML_DIR 327: gui_dialog_number_of_points = create_GUI_dialog_number_of_points(predicate_type, class_name) 328: gui_dialog_number_of_points.set_file(html_path) 329: gui_dialog_number_of_points.show() 330: elsif focus == "POSITION OF POINTS" 331: # Find and show our html file 332: html_path = Sketchup.find_support_file "GUIDialogPositionOfPoints.html" ,Constants::HTML_DIR 333: gui_dialog_position_of_points = create_GUI_dialog_position_of_points(predicate_type, class_name) 334: gui_dialog_position_of_points.set_file(html_path) 335: gui_dialog_position_of_points.show() 336: end 337: 338: end 339: 340: return gui_dialog_points_focus 341: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the position of the points of the current shape
# File lib/interfaces/custom.rb, line 806 806: def create_GUI_dialog_position_of_points(predicate_type, class_name) 807: gui_dialog_position_of_points = UI::WebDialog.new("Configure points position #{predicate_type}", true, "Configure points position #{predicate_type}", 700, 100, 150, 150, true) 808: 809: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 810: gui_dialog_position_of_points.add_action_callback("get_data") do |web_dialog, data| 811: 812: gui_dialog_position_of_points.close 813: data_a = data.split(",") 814: 815: quantification = data_a[0] 816: number = data_a[1] 817: point_type = data_a[2] 818: argument_point_type = data_a[3] 819: relation_type = data_a[4] 820: meters = data_a[5] 821: 822: code = "labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{point_type}\")" 823: if !(argument_point_type == "ORIGIN") 824: code = "#{code} 825: argument_labels = ShadeUtils.get_labels(ShadeUtils.current_shape, \"#{argument_point_type.capitalize}\")" 826: else 827: code = "#{code} 828: p = Point.new(0,0)" 829: end 830: 831: predicate_string = "" 832: 833: case relation_type 834: when "EQUAL" 835: predicate_string = "(l.key.point.distance(p) == #{meters}.m)" 836: when "DIFFERENT" 837: predicate_string = "!(l.key.point.distance(p) == #{meters}.m)" 838: when "BIGGER" 839: predicate_string = "(l.key.point.distance(p) > #{meters}.m)" 840: when "LESS" 841: predicate_string = "(l.key.point.distance(p) < #{meters}.m)" 842: when "BIGGEREQ" 843: predicate_string = "(l.key.point.distance(p) >= #{meters}.m)" 844: when "LESSEQ" 845: predicate_string = "(l.key.point.distance(p) <= #{meters}.m)" 846: end 847: 848: case quantification 849: when "ALL" 850: if !(argument_point_type == "ORIGIN") 851: code = "#{code} 852: ok = true 853: labels.each { |list| 854: list.reset_iterator 855: while l = list.get_next 856: found = false 857: i = 0 858: while ((i < argument_labels.size) && !found) 859: j = 0 860: while ((j < argument_labels[i].size) && !found) 861: if !(l==argument_labels[i].get_node_i(j)) 862: p = argument_labels[i].get_node_i(j).key.point 863: if #{predicate_string} 864: found = true 865: end 866: end 867: j += 1 868: end 869: i += 1 870: end 871: ok = (ok && found) 872: end 873: } 874: result = ok" 875: else 876: code = "#{code} 877: ok = true 878: labels.each { |list| 879: list.reset_iterator 880: while l = list.get_next 881: if !#{predicate_string} 882: ok = false 883: end 884: 885: end 886: } 887: result = ok" 888: end 889: when "NUMBER" 890: if !(argument_point_type == "ORIGIN") 891: code = "#{code} 892: number = #{number} 893: number_l = 0 894: if labels.size > 0 895: labels.each { |list| 896: list.reset_iterator 897: while l = list.get_next 898: i = 0 899: while (i < argument_labels.size) 900: j = 0 901: found = false 902: while ((j < argument_labels[i].size) && !found) 903: if !(l==argument_labels[i].get_node_i(j)) 904: p = argument_labels[i].get_node_i(j).key.point 905: if #{predicate_string} 906: number_l += 1 907: found = true 908: end 909: end 910: j += 1 911: end 912: i += 1 913: end 914: end 915: } 916: result = (number_l >= number) 917: end" 918: 919: else 920: code = "#{code} 921: number_l = 0 922: if labels.size > 0 923: labels.each { |list| 924: list.reset_iterator 925: while l = list.get_next 926: if !#{predicate_string} 927: number_l += 1 928: end 929: end 930: } 931: result = (number_l >= number) 932: end" 933: end 934: 935: end 936: 937: create_code(predicate_type, class_name, code) 938: end 939: 940: return gui_dialog_position_of_points 941: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the rule focus (that is, the “rule id” or the “rule transformation”)
# File lib/interfaces/custom.rb, line 237 237: def create_GUI_dialog_rule(predicate_type, class_name) 238: gui_dialog_rule = UI::WebDialog.new("Choose #{predicate_type} rule focus", true, "Choose #{predicate_type} rule focus", 250, 150, 150, 150, true) 239: 240: # Attach an action callback for getting the chosen focus 241: gui_dialog_rule.add_action_callback("get_focus") do |web_dialog, focus| 242: 243: gui_dialog_rule.close 244: 245: if focus == "RULE ID" 246: # Find and show our html file 247: html_path = Sketchup.find_support_file "GUIDialogRuleID.html" ,Constants::HTML_DIR 248: gui_rule_id = create_GUI_rule_id(predicate_type, class_name) 249: gui_rule_id.set_file(html_path) 250: gui_rule_id.show() 251: elsif focus == "FIRST RULE ID" 252: # Find and show our html file 253: html_path = Sketchup.find_support_file "GUIDialogFirstRuleID.html" ,Constants::HTML_DIR 254: gui_first_rule_id = create_GUI_first_rule_id(predicate_type, class_name) 255: gui_first_rule_id.set_file(html_path) 256: gui_first_rule_id.show() 257: elsif focus == "TRANSFORMATION" 258: # Find and show our html file 259: html_path = Sketchup.find_support_file "GUIDialogRuleTransformation.html" ,Constants::HTML_DIR 260: gui_rule_transformation = create_GUI_rule_transformation(predicate_type, class_name) 261: gui_rule_transformation.set_file(html_path) 262: gui_rule_transformation.show() 263: end 264: 265: end 266: 267: return gui_dialog_rule 268: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the segments of the current shape
# File lib/interfaces/custom.rb, line 949 949: def create_GUI_dialog_segments(predicate_type, class_name) 950: gui_dialog_segments = UI::WebDialog.new("Configure segments #{predicate_type}", true, "Configure segments #{predicate_type}", 700, 100, 150, 150, true) 951: 952: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 953: gui_dialog_segments.add_action_callback("get_data") do |web_dialog, data| 954: 955: gui_dialog_segments.close 956: data_a = data.split(",") 957: 958: quantification = data_a[0] 959: number = data_a[1] 960: relation_type = data_a[2] 961: meters = data_a[3] 962: 963: predicate_string = "" 964: case relation_type 965: when "EQUAL" 966: predicate_string = "(s.key.length == #{meters}.m)" 967: when "DIFFERENT" 968: predicate_string = "!(s.key.length == #{meters}.m)" 969: when "BIGGER" 970: predicate_string = "(s.key.length > #{meters}.m)" 971: when "LESS" 972: predicate_string = "(s.key.length < #{meters}.m)" 973: when "BIGGEREQ" 974: predicate_string = "(s.key.length >= #{meters}.m)" 975: when "LESSEQ" 976: predicate_string = "(s.key.length <= #{meters}.m)" 977: end 978: 979: code = "" 980: 981: case quantification 982: when "ALL" 983: code = "ok = true 984: ShadeUtils.current_shape.s.each_key { |layer_name| 985: ShadeUtils.current_shape.s[layer_name].reset_iterator 986: while s_node = ShadeUtils.current_shape.s[layer_name].get_next 987: s_node.list.reset_iterator 988: while s = s_node.list.get_next 989: if !#{predicate_string} 990: ok = false 991: end 992: end 993: end 994: } 995: result = ok" 996: when "NUMBER" 997: code = "number_s = 0 998: number = #{number} 999: ShadeUtils.current_shape.s.each_key { |layer_name| 1000: ShadeUtils.current_shape.s[layer_name].reset_iterator 1001: while s_node = ShadeUtils.current_shape.s[layer_name].get_next 1002: s_node.list.reset_iterator 1003: while s = s_node.list.get_next 1004: if #{predicate_string} 1005: number_s += 1 1006: end 1007: end 1008: end 1009: } 1010: result = (number_s >= number)" 1011: 1012: end 1013: 1014: create_code(predicate_type, class_name, code) 1015: end 1016: 1017: return gui_dialog_segments 1018: 1019: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the current shape focus (that is, the “whole shape”, the “points” or the “segments”)
# File lib/interfaces/custom.rb, line 277 277: def create_GUI_dialog_shape(predicate_type, class_name) 278: gui_dialog_shape = UI::WebDialog.new("Choose #{predicate_type} shape focus", true, "Choose #{predicate_type} shape focus", 250, 150, 150, 150, true) 279: 280: # Attach an action callback for getting the chosen current shape focus 281: gui_dialog_shape.add_action_callback("get_focus") do |web_dialog, focus| 282: 283: gui_dialog_shape.close 284: 285: if focus == "WHOLE SHAPE" 286: # Find and show our html file 287: html_path = Sketchup.find_support_file "GUIDialogWholeShape.html" ,Constants::HTML_DIR 288: gui_dialog_whole_shape = create_GUI_dialog_whole_shape(predicate_type, class_name) 289: gui_dialog_whole_shape.set_file(html_path) 290: gui_dialog_whole_shape.show() 291: elsif focus == "POINTS" 292: # Find and show our html file 293: html_path = Sketchup.find_support_file "GUIDialogPointsFocus.html" ,Constants::HTML_DIR 294: gui_dialog_points_focus = create_GUI_dialog_points_focus(predicate_type, class_name) 295: gui_dialog_points_focus.set_file(html_path) 296: gui_dialog_points_focus.show() 297: elsif focus == "SEGMENTS" 298: # Find and show our html file 299: html_path = Sketchup.find_support_file "GUIDialogSegments.html" ,Constants::HTML_DIR 300: gui_dialog_segments_focus = create_GUI_dialog_segments(predicate_type, class_name) 301: gui_dialog_segments_focus.set_file(html_path) 302: gui_dialog_segments_focus.show() 303: end 304: 305: end 306: 307: return gui_dialog_shape 308: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the whole shape
# File lib/interfaces/custom.rb, line 594 594: def create_GUI_dialog_whole_shape(predicate_type, class_name) 595: gui_dialog_whole_shape = UI::WebDialog.new("Configure whole shape #{predicate_type}", true, "Configure whole shape #{predicate_type}", 700, 100, 150, 150, true) 596: 597: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 598: gui_dialog_whole_shape.add_action_callback("get_data") do |web_dialog, data| 599: 600: data_a = data.split(",") 601: ok = true 602: 603: relation_type = data_a[0] 604: shape = data_a[1] 605: 606: code = "" 607: 608: ok = true 609: case shape 610: when "AXIOM" 611: code = "shape = ShadeUtils.axiom" 612: when "PREVIOUS SHAPE" 613: code = "shape = ShadeUtils.previous_shape" 614: when "FILE SHAPE" 615: load_shape_path = UI.openpanel "Load Shape", "", "*.txt" 616: code = "shape = LabelledShape.new([], []) 617: shape.load(#{load_shape_path})" 618: when "FILE CONTOUR" 619: chosen_area_path = UI.openpanel("Open area", "" ,"*.area") 620: if chosen_area_path 621: points_string = nil 622: File.open(chosen_area_path, 'r') do |f| 623: while line = f.gets 624: line_a = line.split 625: point = Array.new 626: point[0] = line_a[0].to_f.m 627: point[1] = line_a[1].to_f.m 628: point[2] = line_a[2].to_f.m 629: if points_string 630: points_string = "#{points_string},[#{point[0]}, #{point[1]}, #{point[2]}]" 631: else 632: points_string = "[[#{point[0]}, #{point[1]}, #{point[2]}]" 633: end 634: end 635: points_string = "#{points_string}]" 636: end 637: code = "#{code} 638: shape = true 639: ac = AreaConstraint.new(#{points_string})" 640: else 641: ok = false 642: end 643: end 644: 645: if ok 646: predicate_string = "" 647: 648: case relation_type 649: when "EQUAL" 650: if (shape == "FILE CONTOUR") 651: ok = false 652: UI.messagebox("You cannot use file contour option with equal relation") 653: else 654: predicate_string = "(ShadeUtils.current_shape == shape)" 655: end 656: when "DIFFERENT" 657: if (shape == "FILE CONTOUR") 658: ok = false 659: UI.messagebox("You cannot use file contour option with different relation") 660: else 661: predicate_string = "!(ShadeUtils.current_shape == shape)" 662: end 663: when "SUBSHAPE" 664: if (shape == "FILE CONTOUR") 665: ok = false 666: UI.messagebox("You cannot use file contour option with subshape relation") 667: else 668: code = "#{code} 669: flag_s= shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::SEGMENTS, false) 670: flag_p = shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::POINTS, false)" 671: predicate_string = "(flag_s && flag_p)" 672: end 673: when "SUPERSHAPE" 674: if (shape == "FILE CONTOUR") 675: ok = false 676: UI.messagebox("You cannot use file contour option with supershape relation") 677: else 678: code = "#{code} 679: flag_s= ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::SEGMENTS, false) 680: flag_p = ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::POINTS, false)" 681: predicate_string = "(flag_s && flag_p)" 682: end 683: when "NOT SUBSHAPE" 684: if (shape == "FILE CONTOUR") 685: ok = false 686: UI.messagebox("You cannot use file contour option with subshape relation") 687: else 688: code = "#{code} 689: flag_s= shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::SEGMENTS, false) 690: flag_p = shape.shape_expression(ShadeUtils.current_shape, Constants::SUBSHAPE, Constants::POINTS, false)" 691: predicate_string = "!(flag_s && flag_p)" 692: end 693: when "NOT SUPERSHAPE" 694: if (shape == "FILE CONTOUR") 695: ok = false 696: UI.messagebox("You cannot use file contour option with supershape relation") 697: else 698: code = "#{code} 699: flag_s= ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::SEGMENTS, false) 700: flag_p = ShadeUtils.current_shape.shape_expression(shape, Constants::SUBSHAPE, Constants::POINTS, false)" 701: predicate_string = "!(flag_s && flag_p)" 702: end 703: when "INSIDE" 704: if !(shape == "FILE CONTOUR") 705: ok = false 706: UI.messagebox("You have to specify the file contour option") 707: end 708: predicate_string = "ac.satisfied?" 709: end 710: end 711: 712: if ok 713: gui_dialog_whole_shape.close 714: 715: code = "#{code} 716: result = true 717: if shape 718: result = #{predicate_string} 719: end" 720: create_code(predicate_type, class_name, code) 721: end 722: end 723: 724: return gui_dialog_whole_shape 725: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the first applied rule id
# File lib/interfaces/custom.rb, line 472 472: def create_GUI_first_rule_id(predicate_type, class_name) 473: gui_dialog_first_rule_id = UI::WebDialog.new("Configure first rule id #{predicate_type}", true, "Configure first rule id #{predicate_type}", 700, 100, 150, 150, true) 474: 475: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 476: gui_dialog_first_rule_id.add_action_callback("get_data") do |web_dialog, data| 477: 478: gui_dialog_first_rule_id.close 479: data_a = data.split(",") 480: 481: relation_type = data_a[0] 482: number = data_a[1] 483: 484: predicate_string = "" 485: 486: case relation_type 487: when "EQUAL" 488: predicate_string = "(ShadeUtils.first_rule_id == #{number}" 489: when "DIFFERENT" 490: predicate_string = "!(ShadeUtils.first_rule_id == #{number}" 491: when "BIGGER" 492: predicate_string = "(ShadeUtils.first_rule_id > #{number}" 493: when "LESS" 494: predicate_string = "(ShadeUtils.first_rule_id < #{number}" 495: when "BIGGEREQ" 496: predicate_string = "(ShadeUtils.first_rule_id >= #{number}" 497: when "LESSEQ" 498: predicate_string = "(ShadeUtils.first_rule_id <= #{number}" 499: end 500: 501: 502: code = "if Shade.project.execution.execution_history 503: if Shade.project.execution.execution_history.size == 1 504: result = #{predicate_string}) 505: end 506: end" 507: 508: 509: create_code(predicate_type, class_name, code) 510: end 511: 512: return gui_dialog_first_rule_id 513: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the applied rule id
# File lib/interfaces/custom.rb, line 410 410: def create_GUI_rule_id(predicate_type, class_name) 411: gui_dialog_rule_id = UI::WebDialog.new("Configure rule id #{predicate_type}", true, "Configure rule id #{predicate_type}", 700, 100, 150, 150, true) 412: 413: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 414: gui_dialog_rule_id.add_action_callback("get_data") do |web_dialog, data| 415: 416: gui_dialog_rule_id.close 417: data_a = data.split(",") 418: 419: relation_type = data_a[0] 420: id_type = data_a[1] 421: number = data_a[2] 422: 423: predicate_string = "" 424: 425: case relation_type 426: when "EQUAL" 427: predicate_string = "(ShadeUtils.last_rule_id ==" 428: when "DIFFERENT" 429: predicate_string = "!(ShadeUtils.last_rule_id ==" 430: when "BIGGER" 431: predicate_string = "(ShadeUtils.last_rule_id >" 432: when "LESS" 433: predicate_string = "(ShadeUtils.last_rule_id <" 434: when "BIGGEREQ" 435: predicate_string = "(ShadeUtils.last_rule_id >=" 436: when "LESSEQ" 437: predicate_string = "(ShadeUtils.last_rule_id <=" 438: when "FOLLOWING" 439: predicate_string = "(ShadeUtils.last_rule_id - 1 ==" 440: end 441: 442: code = "" 443: 444: case id_type 445: when "PREVIOUS" 446: predicate_string = "#{predicate_string} ShadeUtils.previous_rule_id" 447: code = "if Shade.project.execution.execution_history 448: if Shade.project.execution.execution_history.size > 1 449: result = #{predicate_string}) 450: end 451: end" 452: when "NUMBER" 453: predicate_string = "#{predicate_string} #{number}" 454: code = "if Shade.project.execution.execution_history 455: result = #{predicate_string}) 456: end" 457: end 458: 459: 460: create_code(predicate_type, class_name, code) 461: end 462: 463: return gui_dialog_rule_id 464: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for configuring the predicate focused in the applied rule transformation
# File lib/interfaces/custom.rb, line 521 521: def create_GUI_rule_transformation(predicate_type, class_name) 522: gui_dialog_rule_transformation = UI::WebDialog.new("Configure rule transformation #{predicate_type}", true, "Configure rule transformation #{predicate_type}", 700, 100, 150, 150, true) 523: 524: # Attach an action callback for getting the input configuration data. This action will also create the string with the main code of the predicate. 525: gui_dialog_rule_transformation.add_action_callback("get_data") do |web_dialog, data| 526: 527: gui_dialog_rule_transformation.close 528: data_a = data.split(",") 529: 530: transformation_type = data_a[0] 531: relation_type = data_a[1] 532: number = data_a[2] 533: 534: code = "" 535: 536: case transformation_type 537: when "XTRASLATION" 538: code = "last_t = ShadeUtils.last_rule_transformation() 539: factor = last_t[2]" 540: when "YTRASLATION" 541: code = "last_t = ShadeUtils.last_rule_transformation() 542: factor = last_t[5]" 543: when "ROTATION" 544: code = "last_t = ShadeUtils.last_rule_transformation() 545: if !(last_t[5] == 0) 546: factor = Math.atan(last_t[4].quo(last_t[5])) 547: elsif !(last_t[0] == 0) 548: factor = Math.atan(-1*(last_t[1].quo(last_t[0]))) 549: elsif (last_t[4] > 0) 550: factor = Math::PI / 2 551: else 552: factor = -1*(Math::PI / 2) 553: end" 554: 555: when "SCALE" 556: code = "last_t = ShadeUtils.last_rule_transformation() 557: factor = Math.sqrt(last_t[0]**2 + last_t[1]**2)" 558: end 559: 560: predicate_string = "" 561: 562: case relation_type 563: when "EQUAL" 564: predicate_string = "(factor == #{number})" 565: when "DIFFERENT" 566: predicate_string = "!(factor == #{number})" 567: when "BIGGER" 568: predicate_string = "(factor > #{number})" 569: when "LESS" 570: predicate_string = "(factor < #{number})" 571: when "BIGGEREQ" 572: predicate_string = "(factor >= #{number})" 573: when "LESSEQ" 574: predicate_string = "(factor <= #{number})" 575: end 576: 577: code = "#{code} 578: if Shade.project.execution.execution_history 579: result = #{predicate_string} 580: end" 581: 582: create_code(predicate_type, class_name, code) 583: end 584: 585: return gui_dialog_rule_transformation 586: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for choosing the type of interface to be used when creating a custom constraint or goal
# File lib/interfaces/custom.rb, line 49 49: def create_choose_interface_dialog(predicate_type, class_name) 50: # Create the WebDialog instance for choosing the interface type 51: choose_interface_dialog = UI::WebDialog.new("Choose interface type", true, "Choose interface type", 250, 150, 150, 150, true) 52: 53: # Attach an action callback 54: choose_interface_dialog.add_action_callback("get_type") do |web_dialog, type| 55: 56: choose_interface_dialog.close 57: 58: if type == "GUI" 59: # Find and show our html file 60: html_path = Sketchup.find_support_file "GUIDialogFocus.html" , Constants::HTML_DIR 61: gui_dialog_focus = create_GUI_dialog_focus(predicate_type, class_name) 62: gui_dialog_focus.set_file(html_path) 63: gui_dialog_focus.show() 64: elsif type == "CODE" 65: # Find and show our html file 66: html_path = Sketchup.find_support_file "write#{predicate_type}CustomCode.html" , Constants::HTML_DIR 67: code_dialog = create_code_dialog(predicate_type, class_name) 68: code_dialog.set_file(html_path) 69: code_dialog.show() 70: end 71: 72: end 73: 74: return choose_interface_dialog 75: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
code | string with the code for the method “satisfied” of either a constraint or a goal |
Method that creates the class and stores the code for a custom constraint or goal
# File lib/interfaces/custom.rb, line 350 350: def create_code(predicate_type, class_name, code) 351: # Create the class 352: bad_sintax = false 353: begin 354: #Define the class without satisfied? method (if the name is properly chosen, then the next eval clause will not raise errors) 355: Object.const_set(class_name, Class.new { 356: 357: eval("attr_reader :name") 358: 359: eval("def initialize; @name = \"#{class_name}\" end") 360: 361: eval("def delete; end") 362: 363: }) 364: 365: code = "#{code} 366: return result" 367: # Define (or re-define) the satisfied? method 368: eval("class #{class_name} 369: 370: def satisfied?; result = true\n #{code}\n end 371: 372: end") 373: rescue Exception => e 374: bad_syntax = true 375: string_errors = e.message.gsub("\n", " ").gsub("\t", " ").gsub(":in `create_execution_toolbar'", "") 376: end 377: 378: if !bad_sintax 379: # Write the code into an auxiliar file 380: file_name = Sketchup.find_support_file Constants::STARTUP_FILE_NAME, Constants::LIB_DIR 381: directory = ShadeUtils.get_directory_from_sketchup_path(file_name) 382: if predicate_type == "Constraint" 383: File.open("#{directory}//#{Constants::CONSTRAINT_FOLDER_NAME}//#{class_name}.txt", 'w') do |f| 384: f.write ("#{code}\n") 385: end 386: # Add the constraint to the project 387: constraint_class = eval("#{class_name}") 388: constraint = constraint_class.new 389: Shade.project.execution.add_constraint(constraint) 390: Shade.add_constraint_class_name([constraint_class, class_name]) 391: else 392: File.open("#{directory}//#{Constants::GOAL_FOLDER_NAME}//#{class_name}.txt", 'w') do |f| 393: f.write ("#{code}\n") 394: end 395: # Add the goal to the project 396: goal_class = eval("#{class_name}") 397: goal = goal_class.new 398: Shade.project.execution.add_goal(goal) 399: Shade.add_goal_class_name([goal_class, class_name]) 400: end 401: end 402: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
class_name | name of the class that will wrap the constraint or the goal |
Method that creates the dialog for directly typing the code of a custom constraint or goal
# File lib/interfaces/custom.rb, line 83 83: def create_code_dialog(predicate_type, class_name) 84: code = nil 85: # Create the WebDialog instance for writing the code 86: code_dialog = UI::WebDialog.new("Write #{predicate_type} custom code", true, "Write #{predicate_type} custom code", 550, 750, 150, 150, true) 87: 88: # Attach an action callback for checking the code syntax 89: code_dialog.add_action_callback("check_syntax") do |web_dialog, code| 90: # Fix the code 91: code.gsub!("<BR>", "\n") 92: code.gsub!("<TAB>", "\t") 93: 94: # Eval the method rescuing the exceptions 95: string_errors = "" 96: begin 97: 98: #Define the class without satisfied? method (if the name is properly chosen, then the next eval clause will not raise errors) 99: Object.const_set(class_name, Class.new { 100: 101: eval("attr_reader :name") 102: 103: eval("def initialize; @name = \"#{class_name}\" end") 104: 105: eval("def delete; end") 106: 107: }) 108: 109: code = "#{code} 110: return result" 111: 112: # Define (or re-define) the satisfied? method 113: eval("class #{class_name} 114: 115: def satisfied?; result = true\n #{code}\n end 116: 117: end") 118: rescue Exception => e 119: bad_syntax = true 120: string_errors = e.message.gsub("\n", " ").gsub("\t", " ").gsub(":in `create_execution_toolbar'", "") 121: end 122: 123: js_command = "" 124: if bad_syntax 125: js_command = "writeSyntaxResults(\"#{string_errors}\")" 126: else 127: js_command = "writeSyntaxResults(\"Syntax OK\")" 128: end 129: web_dialog.execute_script(js_command) 130: end 131: 132: # Attach an action callback for executing the code 133: code_dialog.add_action_callback("execute_code") do |web_dialog, rubish_code| 134: # Execute the method satisfied? rescuing the exceptions 135: # If we are here, it means the method satisfied? has been created 136: string_errors = "" 137: if predicate_type == "Constraint" 138: begin 139: constraint_class = eval("#{class_name}") 140: constraint = constraint_class.new 141: constraint.satisfied? 142: rescue Exception => e 143: bad_execution = true 144: string_errors = e.message.gsub("\n", " ").gsub("\t", " ") 145: end 146: else 147: begin 148: goal_class = eval("#{class_name}") 149: goal = goal_class.new 150: goal.satisfied? 151: rescue Exception => e 152: bad_execution = true 153: string_errors = e.message.gsub("\n", " ").gsub("\t", " ") 154: end 155: end 156: 157: js_command = "" 158: if bad_execution 159: js_command = "writeExecutionResults(\"#{string_errors}\")" 160: else 161: js_command = "writeExecutionResults(\"Execution OK\")" 162: end 163: web_dialog.execute_script(js_command) 164: end 165: 166: # Attach an action callback for saving the code 167: code_dialog.add_action_callback("write_code") do |web_dialog, rubish_code| 168: # Write the code into an auxiliar file 169: file_name = Sketchup.find_support_file Constants::STARTUP_FILE_NAME, Constants::LIB_DIR 170: directory = ShadeUtils.get_directory_from_sketchup_path(file_name) 171: if predicate_type == "Constraint" 172: File.open("#{directory}//#{Constants::CONSTRAINT_FOLDER_NAME}//#{class_name}.txt", 'w') do |f| 173: f.write ("#{code}\n") 174: end 175: # Add the constraint to the project 176: constraint_class = eval("#{class_name}") 177: constraint = constraint_class.new 178: Shade.project.execution.add_constraint(constraint) 179: Shade.add_constraint_class_name([constraint_class, class_name]) 180: else 181: File.open("#{directory}//#{Constants::GOAL_FOLDER_NAME}//#{class_name}.txt", 'w') do |f| 182: f.write ("#{code}\n") 183: end 184: # Add the goal to the project 185: goal_class = eval("#{class_name}") 186: goal = goal_class.new 187: Shade.project.execution.add_goal(goal) 188: Shade.add_goal_class_name([goal_class, class_name]) 189: end 190: 191: # Close the code dialog 192: code_dialog.close 193: end 194: 195: return code_dialog 196: end
Method that creates the toolbar for performing execution tasks
# File lib/interfaces/guitools.rb, line 896 896: def create_execution_toolbar() 897: 898: toolbar = UI.toolbar Constants::EXECUTION_TOOLBAR_NAME 899: 900: # Load Axiom command 901: load_axiom_cmd = UI::Command.new("load_axiom"){ 902: Sketchup.active_model.close_active 903: 904: opened = false 905: while !opened 906: chosen_axiom_path = UI.openpanel("Load axiom", "" ,"*.txt") 907: if chosen_axiom_path 908: if ShadeUtils.get_extension(chosen_axiom_path) == "txt" 909: begin 910: new_axiom = LabelledShape.new(Array.new, Array.new) 911: new_axiom.load(chosen_axiom_path) 912: Shade.project.execution.file_axiom = true 913: Shade.project.execution.grammar.axiom = new_axiom 914: Shade.project.execution.reset 915: opened = true 916: rescue LoadError => e 917: UI.messagebox(e.message) 918: rescue 919: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 920: end 921: else 922: UI.messagebox("Please choose a .txt file") 923: end 924: else 925: opened = true 926: end 927: end 928: } 929: load_axiom_cmd.tooltip = "Load Axiom" 930: load_axiom_cmd.small_icon = File.join(Constants::ICONS_DIR, "load_axiom.PNG") 931: load_axiom_cmd.large_icon = File.join(Constants::ICONS_DIR, "load_axiom.PNG") 932: toolbar.add_item load_axiom_cmd 933: 934: # First-Rule Axiom command 935: first_rule_axiom_cmd = UI::Command.new("first_rule_axiom"){ 936: execution = Shade.project.execution 937: execution.file_axiom = false 938: rule = execution.grammar.rules[0] 939: # Add new axiom 940: new_axiom = LabelledShape.new(Array.new, Array.new) 941: Sketchup.active_model.layers.each { |layer| 942: new_axiom.p[layer.name] = rule.left.p[layer.name].clone 943: new_axiom.s[layer.name] = rule.left.s[layer.name].clone 944: } 945: execution.grammar.axiom = new_axiom 946: 947: execution.reset 948: } 949: first_rule_axiom_cmd.tooltip = "Set the axiom to the first-rule-left shape" 950: first_rule_axiom_cmd.small_icon = File.join(Constants::ICONS_DIR, "first_rule_axiom.PNG") 951: first_rule_axiom_cmd.large_icon = File.join(Constants::ICONS_DIR, "first_rule_axiom.PNG") 952: toolbar.add_item first_rule_axiom_cmd 953: 954: toolbar.add_separator 955: 956: # Execute command 957: exe_cmd = UI::Command.new("apply_rule"){ 958: project = Shade.project 959: execution = Shade.project.execution 960: Sketchup.active_model.close_active 961: 962: prompts = ["Chosen rule id"] 963: default = [1] 964: rule_list = ShadeUtils.create_rule_list() 965: list = [rule_list] 966: input = UI.inputbox prompts, default, list, "Apply Rule" 967: if input 968: chosen_rule_idx = input[0] 969: chosen_rule_id = execution.grammar.rules[chosen_rule_idx.to_i - 1].rule_id 970: 971: #STEP 1: Save temp files 972: save_temp_files() 973: 974: #STEP 2: Call external command with argument: chosen_rule_id 975: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/execute-command.rb" 976: command_directory.gsub!("/", "\\") 977: output = system("ruby \"#{command_directory}\" #{chosen_rule_id}") 978: 979: #STEP 3: Catch return from external command 980: if !($? == 0) 981: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.") 982: #puts output 983: success = execution.apply_rule(chosen_rule_id) 984: if !success 985: UI.messagebox("The rule cannot be applied") 986: end 987: else 988: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log" 989: log_directory.gsub!("/", "\\") 990: File.open(log_directory, 'r') do |f| 991: line = f.gets.strip 992: if (line == "true") 993: load_temp_files() 994: elsif (line == "false") 995: UI.messagebox("The rule cannot be applied") 996: end 997: end 998: end 999: 1000: #STEP 4: delete files of temporal directory 1001: delete_temp_files() 1002: end 1003: } 1004: exe_cmd.tooltip = "Apply rule" 1005: exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute.PNG") 1006: exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute.PNG") 1007: toolbar.add_item exe_cmd 1008: 1009: # Ramdom Execute command 1010: rand_exe_cmd = UI::Command.new("apply_random_rule"){ 1011: project = Shade.project 1012: execution = Shade.project.execution 1013: Sketchup.active_model.close_active 1014: 1015: #STEP 1: Save temp files 1016: save_temp_files() 1017: 1018: #STEP 2: Call external command with argument: chosen_rule_id 1019: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/execute-random-command.rb" 1020: command_directory.gsub!("/", "\\") 1021: system("ruby \"#{command_directory}\"") 1022: 1023: #STEP 3: Catch return from external command 1024: if !($? == 0) 1025: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.") 1026: success = execution.apply_rule_random() 1027: if !success 1028: UI.messagebox("No rule can be applied") 1029: end 1030: else 1031: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log" 1032: log_directory.gsub!("/", "\\") 1033: File.open(log_directory, 'r') do |f| 1034: line = f.gets.strip 1035: if (line == "true") 1036: load_temp_files() 1037: elsif (line == "false") 1038: UI.messagebox("No rule can be applied") 1039: end 1040: end 1041: end 1042: 1043: #STEP 4: delete files of temporal directory 1044: delete_temp_files() 1045: } 1046: rand_exe_cmd.tooltip = "Apply random rule" 1047: rand_exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute_random.PNG") 1048: rand_exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute_random.PNG") 1049: toolbar.add_item rand_exe_cmd 1050: 1051: # Random n-execute command 1052: rand_n_exe_cmd = UI::Command.new("apply_n_random_rules"){ 1053: project = Shade.project 1054: execution = Shade.project.execution 1055: Sketchup.active_model.close_active 1056: 1057: prompts = ["Number of rules", "See steps?"] 1058: default = ["0", "No"] 1059: list = ["", "No|Yes"] 1060: input = UI.inputbox prompts, default, list, "Apply n random rules" 1061: if input 1062: show_backtracking_steps = false 1063: if input[1] == "Yes" 1064: show_backtracking_steps = true 1065: end 1066: if show_backtracking_steps 1067: n_applied = execution.apply_n_rules_random(input[0].to_i, show_backtracking_steps) 1068: if n_applied 1069: UI.messagebox("Success. Number of steps: "+execution.backtracking_steps.to_s) 1070: else 1071: UI.messagebox("Failure. Impossible to apply " + input[0] + " rules.") 1072: end 1073: else #Try external execution 1074: #STEP 1: Save temp files 1075: save_temp_files() 1076: 1077: #STEP 2: Call external command with argument: chosen_rule_id 1078: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/n-execute-random-command.rb" 1079: command_directory.gsub!("/", "\\") 1080: system("ruby \"#{command_directory}\" #{input[0].to_i}") 1081: 1082: #STEP 3: Catch return from external command 1083: if !($? == 0) 1084: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.") 1085: success = execution.apply_n_rules_random(input[0].to_i, false) 1086: if !success 1087: UI.messagebox("The rule cannot be applied") 1088: end 1089: else 1090: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log" 1091: log_directory.gsub!("/", "\\") 1092: File.open(log_directory, 'r') do |f| 1093: line = f.gets.strip 1094: if (line == "false") 1095: UI.messagebox("Failure. Impossible to apply #{input[0]} rules.") 1096: else 1097: load_temp_files() 1098: UI.messagebox("Success. Number of steps: #{line}") 1099: end 1100: end 1101: end 1102: 1103: #STEP 4: delete files of temporal directory 1104: delete_temp_files() 1105: end 1106: end 1107: } 1108: rand_n_exe_cmd.tooltip = "Apply n random rules" 1109: rand_n_exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute_n_random.PNG") 1110: rand_n_exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute_n_random.PNG") 1111: toolbar.add_item rand_n_exe_cmd 1112: 1113: # Random goal-execute command 1114: rand_goal_exe_cmd = UI::Command.new("apply_goal_random_rules"){ 1115: project = Shade.project 1116: execution = Shade.project.execution 1117: Sketchup.active_model.close_active 1118: 1119: if !execution.goals.empty? 1120: 1121: prompts = ["See steps?", "Timeout (secs)?", "Maximum number of rules?"] 1122: default = ["No", "No timeout", "100"] 1123: list = ["No|Yes", "15|30|60|No timeout", ""] 1124: input = UI.inputbox prompts, default, list, "Apply random rules until goals are achieved" 1125: 1126: if input 1127: show_backtracking_steps = false 1128: if input[0] == "Yes" 1129: show_backtracking_steps = true 1130: end 1131: timeout = 0 1132: if input[1] != "No timeout" 1133: timeout = input[2].to_i 1134: end 1135: if input[2] != "No maximum" 1136: n_max_rules = input[2].to_i 1137: end 1138: 1139: if show_backtracking_steps 1140: t1 = Time.now 1141: n_applied = execution.apply_goal_rules_random(show_backtracking_steps, timeout, n_max_rules) 1142: t2 = Time.now 1143: if n_applied 1144: UI.messagebox("Success. Number of steps: "+execution.backtracking_steps.to_s) 1145: else 1146: UI.messagebox("Failure. Impossible to comply the goals") 1147: end 1148: puts "Elapsed time: #{t2 - t1}" 1149: else 1150: #STEP 1: Save temp files 1151: save_temp_files() 1152: 1153: #STEP 2: Call external command with argument: chosen_rule_id 1154: command_directory = "#{File.dirname(__FILE__)}/#{Constants::COMMANDS_DIR}/random-goal-execute-command.rb" 1155: command_directory.gsub!("/", "\\") 1156: t1 = Time.now 1157: system("ruby \"#{command_directory}\" #{timeout} #{n_max_rules}") 1158: t2 = Time.now 1159: 1160: #STEP 3: Catch return from external command 1161: if !($? == 0) 1162: UI.messagebox("The loaded constraints/goals use some functions of SketchUp API. The execution will be performed inside the SketchUp environment, and it may take more time.") 1163: t1 = Time.now 1164: n_applied = execution.apply_goal_rules_random(show_backtracking_steps, timeout, n_max_rules) 1165: t2 = Time.now 1166: puts "Elapsed time: #{t2 - t1}" 1167: if n_applied == 1 1168: UI.messagebox("No goals are speficied") 1169: elsif n_applied 1170: UI.messagebox("Success. Number of steps: #{execution.backtracking_steps.to_s}") 1171: else 1172: UI.messagebox("Failure. Impossible to satisfy the specified goals") 1173: end 1174: else 1175: log_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/result.log" 1176: log_directory.gsub!("/", "\\") 1177: File.open(log_directory, 'r') do |f| 1178: line = f.gets 1179: if (line == "false") 1180: UI.messagebox("Failure. Impossible to satisfy the specified goals") 1181: else 1182: load_temp_files() 1183: UI.messagebox("Success. Number of steps: #{line}") 1184: puts "Elapsed time: #{t2 - t1}" 1185: end 1186: end 1187: end 1188: 1189: #STEP 4: delete files of temporal directory 1190: delete_temp_files() 1191: end 1192: end 1193: else 1194: UI.messagebox("No goals are speficied") 1195: end 1196: 1197: } 1198: rand_goal_exe_cmd.tooltip = "Apply random rules until goals are achieved" 1199: rand_goal_exe_cmd.small_icon = File.join(Constants::ICONS_DIR, "execute_goal_random.PNG") 1200: rand_goal_exe_cmd.large_icon = File.join(Constants::ICONS_DIR, "execute_goal_random.PNG") 1201: toolbar.add_item rand_goal_exe_cmd 1202: 1203: # Undo step command 1204: undo_step_cmd = UI::Command.new("undo_step"){ 1205: project = Shade.project 1206: execution = Shade.project.execution 1207: Sketchup.active_model.close_active 1208: 1209: execution.undo 1210: } 1211: undo_step_cmd.tooltip = "Undo Step" 1212: undo_step_cmd.small_icon = File.join(Constants::ICONS_DIR, "undo.PNG") 1213: undo_step_cmd.large_icon = File.join(Constants::ICONS_DIR, "undo.PNG") 1214: toolbar.add_item undo_step_cmd 1215: 1216: # Reset command 1217: reset_cmd = UI::Command.new("reset"){ 1218: project = Shade.project 1219: execution = Shade.project.execution 1220: Sketchup.active_model.close_active 1221: 1222: execution.reset 1223: } 1224: reset_cmd.tooltip = "Reset" 1225: reset_cmd.small_icon = File.join(Constants::ICONS_DIR, "reset.PNG") 1226: reset_cmd.large_icon = File.join(Constants::ICONS_DIR, "reset.PNG") 1227: toolbar.add_item reset_cmd 1228: 1229: #Show labels command 1230: show_cmd = UI::Command.new("show_labels"){ 1231: project = Shade.project 1232: execution = Shade.project.execution 1233: Sketchup.active_model.close_active 1234: execution.show_labels = true 1235: project.refresh() 1236: } 1237: show_cmd.tooltip = "Show labels" 1238: show_cmd.small_icon = File.join(Constants::ICONS_DIR, "show_labels.PNG") 1239: show_cmd.large_icon = File.join(Constants::ICONS_DIR, "show_labels.PNG") 1240: toolbar.add_item show_cmd 1241: 1242: #Hide labels command 1243: hide_cmd = UI::Command.new("hide_labels"){ 1244: project = Shade.project 1245: execution = Shade.project.execution 1246: Sketchup.active_model.close_active 1247: execution.show_labels = false 1248: project.refresh() 1249: } 1250: hide_cmd.tooltip = "Hide labels" 1251: hide_cmd.small_icon = File.join(Constants::ICONS_DIR, "hide_labels.PNG") 1252: hide_cmd.large_icon = File.join(Constants::ICONS_DIR, "hide_labels.PNG") 1253: toolbar.add_item hide_cmd 1254: 1255: #Change size of labels command 1256: change_label_radius_cmd = UI::Command.new("change_label_radius"){ 1257: prompts = ["New radius (between 0.1 and 0.9)"] 1258: default = [0.5] 1259: list = [""] 1260: input = UI.inputbox prompts, default, list, "New radius of labels" 1261: if input 1262: Shade.label_radius = input[0].to_f.m 1263: project = Shade.project 1264: execution = Shade.project.execution 1265: Sketchup.active_model.close_active 1266: project.refresh(true) 1267: end 1268: } 1269: change_label_radius_cmd.tooltip = "Change label radius" 1270: change_label_radius_cmd.small_icon = File.join(Constants::ICONS_DIR, "change_label_radius.PNG") 1271: change_label_radius_cmd.large_icon = File.join(Constants::ICONS_DIR, "change_label_radius.PNG") 1272: toolbar.add_item change_label_radius_cmd 1273: 1274: toolbar.add_separator 1275: 1276: # Save Design command 1277: save_design_cmd = UI::Command.new("save_design"){ 1278: project = Shade.project 1279: execution = Shade.project.execution 1280: Sketchup.active_model.close_active 1281: 1282: saved = false 1283: while !saved 1284: path_to_save_to = UI.savepanel "Save Design", "", "design.txt" 1285: if (path_to_save_to) 1286: if ShadeUtils.get_extension(path_to_save_to) == "txt" 1287: begin 1288: execution.current_shape.save(path_to_save_to) 1289: saved = true 1290: rescue 1291: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 1292: end 1293: else 1294: UI.messagebox("Please save the design as a .txt file") 1295: end 1296: else 1297: saved = true 1298: end 1299: end 1300: } 1301: save_design_cmd.tooltip = "Save Design" 1302: save_design_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_design.PNG") 1303: save_design_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_design.PNG") 1304: toolbar.add_item save_design_cmd 1305: 1306: toolbar.add_separator 1307: 1308: toolbar.show 1309: end
Method that creates the toolbar for dealing with constraints and goals
# File lib/interfaces/guitools.rb, line 1312 1312: def create_guidance_toolbar 1313: toolbar = UI.toolbar Constants::GUIDANCE_TOOLBAR_NAME 1314: 1315: #Add constraint command 1316: add_constraint_cmd = UI::Command.new("add_constraint"){ 1317: project = Shade.project 1318: execution = Shade.project.execution 1319: Sketchup.active_model.close_active 1320: 1321: prompts = ["Constraint: "] 1322: default = [Constants::DISTINCT_SHAPE_CONSTRAINT_NAME] 1323: 1324: array_list = "" 1325: Shade.constraint_class_names.each { |pair| 1326: array_list += "#{pair[1]}|" 1327: } 1328: list = [array_list[0..array_list.size-2]] 1329: input = UI.inputbox prompts, default, list, "Constraint to add" 1330: if input 1331: result = false 1332: if input[0] == Constants::AREA_CONSTRAINT_NAME 1333: prompts = ["Points: "] 1334: default = ["Default"] 1335: list = ["Default|From File"] 1336: input = UI.inputbox prompts, default, list, "Choose points" 1337: if input 1338: if input[0] == "Default" 1339: points = Constants::PTS_AREA.clone 1340: elsif input[0] == "From File" 1341: # TODO: make compatible with different OOSS (masks) 1342: chosen_area_path = UI.openpanel("Open area", "" ,"*.area") 1343: points = [] 1344: File.open(chosen_area_path, 'r') do |f| 1345: while line = f.gets 1346: line_a = line.split 1347: point = Array.new 1348: point[0] = line_a[0].to_f.m 1349: point[1] = line_a[1].to_f.m 1350: point[2] = line_a[2].to_f.m 1351: points.push point 1352: end 1353: end 1354: end 1355: result = project.execution.add_constraint(AreaConstraint.new(points)) 1356: end 1357: else 1358: i = 0 1359: found = false 1360: constraint_class = nil 1361: while ((i < Shade.constraint_class_names.size) && !found) 1362: if (Shade.constraint_class_names[i][1] == input[0]) 1363: found = true 1364: constraint_class = Shade.constraint_class_names[i][0] 1365: end 1366: i+=1 1367: end 1368: if constraint_class 1369: result = project.execution.add_constraint(constraint_class.new) 1370: end 1371: end 1372: if !result 1373: UI.messagebox("The grammar already has the "+input[0]+" Constraint") 1374: end 1375: end 1376: } 1377: add_constraint_cmd.tooltip = "Add Constraint" 1378: add_constraint_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_constraint.PNG") 1379: add_constraint_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_constraint.PNG") 1380: toolbar.add_item add_constraint_cmd 1381: 1382: #Add custom constraint command 1383: add_custom_constraint_cmd = UI::Command.new("add_custom_constraint"){ 1384: 1385: # Find and show our html file 1386: html_path = Sketchup.find_support_file "chooseName.html" ,Constants::HTML_DIR 1387: name_dialog = create_name_dialog("Constraint") 1388: name_dialog.set_file(html_path) 1389: name_dialog.show() 1390: } 1391: add_custom_constraint_cmd.tooltip = "Add Custom Constraint" 1392: add_custom_constraint_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_custom_constraint.PNG") 1393: add_custom_constraint_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_custom_constraint.PNG") 1394: toolbar.add_item add_custom_constraint_cmd 1395: 1396: #Remove constraint command 1397: remove_constraint_cmd = UI::Command.new("remove_constraint"){ 1398: project = Shade.project 1399: execution = Shade.project.execution 1400: Sketchup.active_model.close_active 1401: 1402: prompts = ["Constraint: "] 1403: default = [Constants::DISTINCT_SHAPE_CONSTRAINT_NAME] 1404: 1405: array_list = "" 1406: Shade.constraint_class_names.each { |pair| 1407: array_list += "#{pair[1]}|" 1408: } 1409: list = [array_list[0..array_list.size-2]] 1410: input = UI.inputbox prompts, default, list, "Constraint to remove" 1411: if input 1412: result = project.execution.delete_constraint(input[0]) 1413: if !result 1414: UI.messagebox("The grammar does not have the "+input[0]+" Constraint") 1415: end 1416: end 1417: #Here we do not have to reset the design, as the execution will be the same 1418: } 1419: remove_constraint_cmd.tooltip = "Remove Constraint" 1420: remove_constraint_cmd.small_icon = File.join(Constants::ICONS_DIR, "remove_constraint.PNG") 1421: remove_constraint_cmd.large_icon = File.join(Constants::ICONS_DIR, "remove_constraint.PNG") 1422: toolbar.add_item remove_constraint_cmd 1423: 1424: # Project Constraints command 1425: project_constraints_cmd = UI::Command.new("project_constraints"){ 1426: project = Shade.project 1427: execution = Shade.project.execution 1428: constraints = "" 1429: execution.constraints.each{ |r| 1430: constraints = constraints + r.name + "\n" 1431: } 1432: UI.messagebox("Present Constraints on #{project.title}:\n "+constraints) 1433: } 1434: project_constraints_cmd.tooltip = "Project constraints" 1435: project_constraints_cmd.small_icon = File.join(Constants::ICONS_DIR, "project_constraints.PNG") 1436: project_constraints_cmd.large_icon = File.join(Constants::ICONS_DIR, "project_constraints.PNG") 1437: toolbar.add_item project_constraints_cmd 1438: 1439: toolbar.add_separator 1440: 1441: # Add goal command 1442: add_goal_command = UI::Command.new("add_goal"){ 1443: project = Shade.project 1444: execution = Shade.project.execution 1445: Sketchup.active_model.close_active 1446: 1447: prompts = ["Goal: "] 1448: default = [Constants::NO_LABELS_GOAL_NAME] 1449: 1450: array_list = "" 1451: Shade.goal_class_names.each { |pair| 1452: array_list += "#{pair[1]}|" 1453: } 1454: list = [array_list[0..array_list.size-2]] 1455: input = UI.inputbox prompts, default, list, "Goal to add" 1456: if input 1457: result = false 1458: i = 0 1459: found = false 1460: goal_class = nil 1461: while ((i < Shade.goal_class_names.size) && !found) 1462: if (Shade.goal_class_names[i][1] == input[0]) 1463: found = true 1464: goal_class = Shade.goal_class_names[i][0] 1465: end 1466: i+=1 1467: end 1468: if goal_class 1469: result = project.execution.add_goal(goal_class.new) 1470: end 1471: if !result 1472: UI.messagebox("The grammar already has the "+input[0]+" goal") 1473: end 1474: end 1475: } 1476: add_goal_command.tooltip = "Add Goal" 1477: add_goal_command.small_icon = File.join(Constants::ICONS_DIR, "add_goal.PNG") 1478: add_goal_command.large_icon = File.join(Constants::ICONS_DIR, "add_goal.PNG") 1479: toolbar.add_item add_goal_command 1480: 1481: #Add custom goal command 1482: add_custom_goal_cmd = UI::Command.new("add_custom_goal"){ 1483: # Find and show our html file 1484: html_path = Sketchup.find_support_file "chooseName.html" ,Constants::HTML_DIR 1485: name_dialog = create_name_dialog("Goal") 1486: name_dialog.set_file(html_path) 1487: name_dialog.show() 1488: } 1489: add_custom_goal_cmd.tooltip = "Add Custom Goal" 1490: add_custom_goal_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_custom_goal.PNG") 1491: add_custom_goal_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_custom_goal.PNG") 1492: toolbar.add_item add_custom_goal_cmd 1493: 1494: # Remove goal command 1495: remove_goal_command = UI::Command.new("remove_goal"){ 1496: project = Shade.project 1497: execution = Shade.project.execution 1498: Sketchup.active_model.close_active 1499: 1500: prompts = ["Goal: "] 1501: default = [Constants::NO_LABELS_GOAL_NAME] 1502: 1503: array_list = "" 1504: Shade.goal_class_names.each { |pair| 1505: array_list += "#{pair[1]}|" 1506: } 1507: list = [array_list[0..array_list.size-2]] 1508: input = UI.inputbox prompts, default, list, "Goal to remove" 1509: if input 1510: result = project.execution.delete_goal(input[0]) 1511: if !result 1512: UI.messagebox("The grammar does not have the "+input[0]+" goal") 1513: end 1514: end 1515: } 1516: remove_goal_command.tooltip = "Remove Goal" 1517: remove_goal_command.small_icon = File.join(Constants::ICONS_DIR, "remove_goal.PNG") 1518: remove_goal_command.large_icon = File.join(Constants::ICONS_DIR, "remove_goal.PNG") 1519: toolbar.add_item remove_goal_command 1520: 1521: # Project Goals command 1522: project_goals_cmd = UI::Command.new("project_goals"){ 1523: project = Shade.project 1524: execution = Shade.project.execution 1525: goals = "" 1526: execution.goals.each{ |g| 1527: goals = goals + g.name + "\n" 1528: } 1529: UI.messagebox("Present Goals on #{project.title}:\n "+goals) 1530: } 1531: project_goals_cmd.tooltip = "Project Goals" 1532: project_goals_cmd.small_icon = File.join(Constants::ICONS_DIR, "project_goals.PNG") 1533: project_goals_cmd.large_icon = File.join(Constants::ICONS_DIR, "project_goals.PNG") 1534: toolbar.add_item project_goals_cmd 1535: 1536: # Satisfy Goals command 1537: satisfy_goals_command = UI::Command.new("satisfy_goals"){ 1538: project = Shade.project 1539: execution = Shade.project.execution 1540: if execution.goals_satisfied? 1541: UI.messagebox("The goals are satisfied") 1542: else 1543: UI.messagebox("The goals are not satisfied") 1544: end 1545: } 1546: satisfy_goals_command.tooltip = "Satisfy Goals?" 1547: satisfy_goals_command.small_icon = File.join(Constants::ICONS_DIR, "satisfy_goals.PNG") 1548: satisfy_goals_command.large_icon = File.join(Constants::ICONS_DIR, "satisfy_goals.PNG") 1549: toolbar.add_item satisfy_goals_command 1550: 1551: toolbar.add_separator 1552: 1553: # Create robot command 1554: create_robot_command = UI::Command.new("create_script"){ 1555: Sketchup.active_model.close_active 1556: # Find and show our html file 1557: html_path = Sketchup.find_support_file "createRobot.html" , Constants::HTML_DIR 1558: robot_dialog = create_robot_dialog 1559: robot_dialog.set_file(html_path) 1560: robot_dialog.show() 1561: } 1562: create_robot_command.tooltip = "Create script" 1563: create_robot_command.small_icon = File.join(Constants::ICONS_DIR, "create_robot.PNG") 1564: create_robot_command.large_icon = File.join(Constants::ICONS_DIR, "create_robot.PNG") 1565: toolbar.add_item create_robot_command 1566: 1567: # Load robot command 1568: load_robot_command = UI::Command.new("load_script"){ 1569: Sketchup.active_model.close_active 1570: chosen_robot_path = UI.openpanel("Open script", "" ,"*.txt") 1571: if chosen_robot_path 1572: robot = Robot.new 1573: robot.load(chosen_robot_path) 1574: Shade.robot = robot 1575: end 1576: } 1577: load_robot_command.tooltip = "Load script" 1578: load_robot_command.small_icon = File.join(Constants::ICONS_DIR, "load_robot.PNG") 1579: load_robot_command.large_icon = File.join(Constants::ICONS_DIR, "load_robot.PNG") 1580: toolbar.add_item load_robot_command 1581: 1582: # Execute robot command 1583: execute_robot_command = UI::Command.new("execute_script"){ 1584: Sketchup.active_model.close_active 1585: if Shade.robot 1586: prompts = ["Number of designs"] 1587: default = ["1"] 1588: list = [] 1589: input = UI.inputbox prompts, default, list, "Number of designs to generate" 1590: 1591: if input 1592: chosen_design_path = UI.savepanel("Save designs", "" ,"design.txt") 1593: if chosen_design_path 1594: 1595: Shade.robot.execute(input[0], File.dirname(chosen_design_path)) 1596: Shade.project.refresh(true) 1597: UI.beep 1598: end 1599: end 1600: else 1601: UI.messagebox("No script has been loaded") 1602: end 1603: } 1604: execute_robot_command.tooltip = "Execute script" 1605: execute_robot_command.small_icon = File.join(Constants::ICONS_DIR, "execute_robot.PNG") 1606: execute_robot_command.large_icon = File.join(Constants::ICONS_DIR, "execute_robot.PNG") 1607: toolbar.add_item execute_robot_command 1608: 1609: toolbar.show 1610: 1611: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
predicate_type | “Constraint” or “Goal” |
Method that creates the dialog for choosing the name of a custom constraint or goal
# File lib/interfaces/custom.rb, line 13 13: def create_name_dialog(predicate_type) 14: 15: name = nil 16: # Create the WebDialog instance for choosing the name 17: name_dialog = UI::WebDialog.new("Choose #{predicate_type} name", true, "Choose #{predicate_type} name", 250, 150, 150, 150, true) 18: 19: # Attach an action callback 20: name_dialog.add_action_callback("get_name") do |web_dialog, name| 21: 22: #Obtain the class name 23: class_name = name.gsub(" ", "_") 24: class_name[0] = class_name[0].chr.to_s.upcase 25: 26: #If class_name is not used... 27: if !Object.const_defined?(class_name) 28: 29: name_dialog.close 30: # Find and show our html file 31: html_path = Sketchup.find_support_file "chooseInterfaceType.html" , Constants::HTML_DIR 32: choose_interface_dialog = create_choose_interface_dialog(predicate_type, class_name) 33: choose_interface_dialog.set_file(html_path) 34: choose_interface_dialog.show() 35: else 36: UI.messagebox("The name is already in use") 37: end 38: end 39: 40: return name_dialog 41: end
Author | Manuela Ruiz (mruiz@lcc.uma.es) |
Method that creates the dialog for configuring a design script that will be able to execute a number of projects in a sequential manner
# File lib/interfaces/custom.rb, line 1024 1024: def create_robot_dialog 1025: gui_dialog_robot = UI::WebDialog.new("Create new design script", true, "Create new design script", 500, 300, 150, 150, true) 1026: 1027: Shade.robot = Robot.new 1028: 1029: # Attach an action callback for saving the script 1030: gui_dialog_robot.add_action_callback("save_robot") do |web_dialog, kk| 1031: 1032: if Shade.robot.project_paths.size > 0 1033: 1034: path_to_save_to = UI.savepanel "Save Script", "", "script.txt" 1035: if path_to_save_to 1036: Shade.robot.save(path_to_save_to) 1037: gui_dialog_robot.close 1038: end 1039: 1040: else 1041: UI.messagebox("There are no projects added") 1042: end 1043: 1044: end 1045: 1046: # Attach an action callback for adding a project to the script 1047: gui_dialog_robot.add_action_callback("add_project") do |web_dialog, kk| 1048: 1049: project_path = UI.openpanel("Open project", "" ,"*.prj") 1050: prompts = ["Execution mode"] 1051: default = ["Goals"] 1052: list = ["Goals|Number of rules"] 1053: input = UI.inputbox prompts, default, list, "Execution mode" 1054: 1055: if input 1056: execution_mode = input[0] 1057: mode_string = input[0].to_s 1058: ok = true 1059: if !(input[0] == "Goals") 1060: prompts = ["Number of rules"] 1061: default = ["1"] 1062: list = [] 1063: n_input = UI.inputbox prompts, default, list, "Number of rules" 1064: 1065: if n_input 1066: mode_string = "#{n_input[0]} rules" 1067: execution_mode = n_input[0] 1068: 1069: else 1070: ok = false 1071: end 1072: end 1073: if ok 1074: Shade.robot.project_paths.push project_path 1075: Shade.robot.execution_modes.push execution_mode 1076: project_info_string = "#{ShadeUtils.get_title_from_path(project_path)}:#{mode_string}" 1077: js_command = "writeProjectInfo(\"#{project_info_string}\")" 1078: web_dialog.execute_script(js_command) 1079: end 1080: end 1081: 1082: end 1083: 1084: return gui_dialog_robot 1085: end
Method that creates the toolbar for saving and loading projects, grammars and shapes, as well as editing rules
# File lib/interfaces/guitools.rb, line 237 237: def create_static_toolbar() 238: 239: toolbar = UI.toolbar Constants::STATIC_TOOLBAR_NAME 240: 241: #New Project command 242: newp_cmd = UI::Command.new("new_project"){ 243: project = Shade.project 244: execution = Shade.project.execution 245: Sketchup.active_model.close_active 246: execution.reset 247: 248: #Before creating a new project, we save the current one if necessary 249: if !project.saved 250: input = UI.messagebox("Save current project?", MB_YESNOCANCEL) 251: if input == 6 252: if project.path 253: project.save(project.path, true) 254: else 255: saved = false 256: while !saved 257: path_to_save_to = UI.savepanel "Save Project", "", "project.prj" 258: if path_to_save_to 259: if ShadeUtils.get_extension(path_to_save_to) == "prj" 260: begin 261: project.save(path_to_save_to, true) 262: saved = true 263: rescue 264: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 265: end 266: else 267: UI.messagebox("Please save the project as a .prj file") 268: end 269: else 270: saved = true 271: end 272: end 273: end 274: end 275: end 276: ShadeUtils.create_default_new_project() 277: } 278: newp_cmd.tooltip = "New project" 279: newp_cmd.small_icon = File.join(Constants::ICONS_DIR, "new_project.PNG") 280: newp_cmd.large_icon = File.join(Constants::ICONS_DIR, "new_project.PNG") 281: toolbar.add_item newp_cmd 282: 283: #Open Project command 284: openp_cmd = UI::Command.new("open_project"){ 285: project = Shade.project 286: execution = Shade.project.execution 287: Sketchup.active_model.close_active 288: #execution.reset 289: 290: if !project.saved 291: input = UI.messagebox("Save current project?", MB_YESNOCANCEL) 292: if input == 6 293: if project.path 294: project.save(project.path, true) 295: else 296: saved = false 297: while !saved 298: path_to_save_to = UI.savepanel "Save Project", "", "project.prj" 299: if path_to_save_to 300: if ShadeUtils.get_extension(path_to_save_to) == "prj" 301: begin 302: project.save(path_to_save_to, true) 303: saved = true 304: rescue 305: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 306: end 307: else 308: UI.messagebox("Please save the project as a .prj file") 309: end 310: else 311: saved = true 312: end 313: end 314: end 315: end 316: end 317: 318: opened = false 319: while !opened 320: chosen_project_path = UI.openpanel("Open project", "" ,"*.prj") 321: if chosen_project_path 322: if ShadeUtils.get_extension(chosen_project_path) == "prj" 323: begin 324: project.load(chosen_project_path) 325: project.saved = true 326: project.refresh 327: opened = true 328: rescue 329: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 330: rescue LoadError => e 331: UI.messagebox(e.message) 332: end 333: else 334: UI.messagebox("Please choose a .prj file") 335: end 336: else 337: opened = true 338: end 339: end 340: 341: } 342: openp_cmd.tooltip = "Open project" 343: openp_cmd.small_icon = File.join(Constants::ICONS_DIR, "open_project.PNG") 344: openp_cmd.large_icon = File.join(Constants::ICONS_DIR, "open_project.PNG") 345: toolbar.add_item openp_cmd 346: 347: #Save Project command 348: savep_cmd = UI::Command.new("save_project"){ 349: project = Shade.project 350: execution = Shade.project.execution 351: Sketchup.active_model.close_active 352: 353: if project.path 354: project.save(project.path, true) 355: else 356: saved = false 357: while !saved 358: path_to_save_to = UI.savepanel "Save Project", "", "project.prj" 359: if path_to_save_to 360: if ShadeUtils.get_extension(path_to_save_to) == "prj" 361: begin 362: project.save(path_to_save_to, true) 363: saved = true 364: rescue 365: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 366: end 367: else 368: UI.messagebox("Please save the project as a .prj file") 369: end 370: else 371: saved = true 372: end 373: end 374: end 375: } 376: savep_cmd.tooltip = "Save project" 377: savep_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_project.PNG") 378: savep_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_project.PNG") 379: toolbar.add_item savep_cmd 380: 381: #Save Project as command 382: savepas_cmd = UI::Command.new("save_project_as"){ 383: project = Shade.project 384: execution = Shade.project.execution 385: Sketchup.active_model.close_active 386: 387: saved = false 388: while !saved 389: path_to_save_to = UI.savepanel "Save Project", "", "project.prj" 390: if path_to_save_to 391: if ShadeUtils.get_extension(path_to_save_to) == "prj" 392: begin 393: project.save(path_to_save_to, true) 394: saved = true 395: rescue 396: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 397: end 398: else 399: UI.messagebox("Please save the project as a .prj file") 400: end 401: else 402: saved = true 403: end 404: end 405: 406: } 407: savepas_cmd.tooltip = "Save project as" 408: savepas_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_project_as.PNG") 409: savepas_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_project_as.PNG") 410: toolbar.add_item savepas_cmd 411: 412: toolbar.add_separator 413: 414: #New Grammar command 415: newg_cmd = UI::Command.new("new_grammar"){ 416: project = Shade.project 417: execution = Shade.project.execution 418: Sketchup.active_model.close_active 419: execution.reset 420: 421: if !execution.grammar.saved 422: input = UI.messagebox("Save current grammar?", MB_YESNOCANCEL) 423: if input == 6 424: saved = false 425: while !saved 426: path_to_save_to = UI.savepanel "Save Grammar", "", "grammar.gr2" 427: if path_to_save_to 428: if ShadeUtils.get_extension(path_to_save_to) == "gr2" 429: begin 430: execution.grammar.save(path_to_save_to, true) 431: saved = true 432: rescue 433: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 434: end 435: else 436: UI.messagebox("Please save the grammar as a .gr2 file") 437: end 438: else 439: saved = true 440: end 441: end 442: end 443: end 444: ShadeUtils.create_default_new_grammar() 445: project.saved = false 446: project.refresh 447: } 448: newg_cmd.tooltip = "New grammar" 449: newg_cmd.small_icon = File.join(Constants::ICONS_DIR, "new_grammar.PNG") 450: newg_cmd.large_icon = File.join(Constants::ICONS_DIR, "new_grammar.PNG") 451: toolbar.add_item newg_cmd 452: 453: #Open Grammar command 454: openg_cmd = UI::Command.new("open_grammar"){ 455: project = Shade.project 456: execution = Shade.project.execution 457: Sketchup.active_model.close_active 458: execution.reset 459: 460: if !execution.grammar.saved 461: input = UI.messagebox("Save current grammar?", MB_YESNOCANCEL) 462: if input == 6 463: saved = false 464: while !saved 465: path_to_save_to = UI.savepanel "Save Grammar", "", "grammar.gr2" 466: if path_to_save_to 467: if ShadeUtils.get_extension(path_to_save_to) == "gr2" 468: begin 469: execution.grammar.save(path_to_save_to, true) 470: saved = true 471: rescue 472: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 473: end 474: else 475: UI.messagebox("Please save the grammar as a .gr2 file") 476: end 477: else 478: saved = true 479: end 480: end 481: end 482: end 483: 484: opened = false 485: while !opened 486: chosen_grammar_path = UI.openpanel("Open grammar", "" ,"*.gr2") 487: if chosen_grammar_path 488: if ShadeUtils.get_extension(chosen_grammar_path) == "gr2" 489: begin 490: execution.grammar.load(chosen_grammar_path) 491: opened = true 492: project.saved = false 493: project.refresh 494: rescue LoadError => e 495: UI.messagebox(e.message) 496: rescue 497: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 498: end 499: else 500: UI.messagebox("Please choose a .gr2 file") 501: end 502: else 503: opened = true 504: end 505: end 506: } 507: openg_cmd.tooltip = "Open grammar" 508: openg_cmd.small_icon = File.join(Constants::ICONS_DIR, "open_grammar.PNG") 509: openg_cmd.large_icon = File.join(Constants::ICONS_DIR, "open_grammar.PNG") 510: toolbar.add_item openg_cmd 511: 512: #Save Grammar As command 513: savegas_cmd = UI::Command.new("save_grammar_as"){ 514: project = Shade.project 515: execution = Shade.project.execution 516: Sketchup.active_model.close_active 517: saved = false 518: while !saved 519: path_to_save_to = UI.savepanel "Save Grammar", "", "grammar.gr2" 520: if path_to_save_to 521: if ShadeUtils.get_extension(path_to_save_to) == "gr2" 522: begin 523: execution.grammar.save(path_to_save_to, true) 524: saved = true 525: rescue 526: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 527: end 528: else 529: UI.messagebox("Please save the grammar as a .gr2 file") 530: end 531: else 532: saved = true 533: end 534: end 535: } 536: savegas_cmd.tooltip = "Save grammar as" 537: savegas_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_grammar_as.PNG") 538: savegas_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_grammar_as.PNG") 539: toolbar.add_item savegas_cmd 540: 541: toolbar.add_separator 542: 543: #Add Rule command 544: add_rule_cmd = UI::Command.new("add_rule"){ 545: project = Shade.project 546: execution = Shade.project.execution 547: Sketchup.active_model.close_active 548: 549: size = execution.grammar.rules.size 550: 551: #Create the default shapes 552: left = ShadeUtils.create_default_left_shape 553: right = ShadeUtils.create_default_right_shape 554: 555: #Obtain new rule id 556: last_id = execution.grammar.rules[size-1].rule_id 557: 558: #Create new rule 559: new_rule = ShadeUtils.paint_rule(last_id+1, left, right) 560: execution.grammar.add_rule(new_rule) 561: project.refresh 562: } 563: add_rule_cmd.tooltip = "Add rule" 564: add_rule_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_rule.PNG") 565: add_rule_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_rule.PNG") 566: toolbar.add_item add_rule_cmd 567: 568: #Delete Rule command 569: delete_rule_cmd = UI::Command.new("delete_rule"){ 570: project = Shade.project 571: execution = Shade.project.execution 572: Sketchup.active_model.close_active 573: 574: if execution.grammar.rules.size > 1 575: prompts = ["Rule to delete: "] 576: default = ["1"] 577: rule_list = ShadeUtils.create_rule_list() 578: list = [rule_list] 579: input = UI.inputbox prompts, default, list, "Delete Rule" 580: if input 581: chosen_rule_idx = input[0].to_i-1 582: 583: if ((chosen_rule_idx == 0) && (!execution.file_axiom)) 584: previous_rule = execution.grammar.rules[1] 585: # Add new axiom 586: new_axiom = LabelledShape.new(Array.new, Array.new) 587: Sketchup.active_model.layers.each { |layer| 588: new_axiom.p[layer.name] = previous_rule.left.p[layer.name].clone 589: new_axiom.s[layer.name] = previous_rule.left.s[layer.name].clone 590: } 591: execution.grammar.axiom = new_axiom 592: 593: execution.reset 594: end 595: execution.grammar.remove_rule(chosen_rule_idx) 596: # Transform the position of the rules from chosen_rule_idx 597: idx = chosen_rule_idx 598: 599: while idx < execution.grammar.rules.size 600: 601: current_rule = execution.grammar.rules[idx] 602: 603: current_rule.left.layout_transformation = current_rule.left.layout_transformation * Constants::DESCEND_T.inverse 604: current_rule.right.layout_transformation = current_rule.right.layout_transformation * Constants::DESCEND_T.inverse 605: 606: current_rule.left.changed = true 607: current_rule.right.changed = true 608: 609: Sketchup.active_model.layers.each { |layer| 610: current_rule.arrow_group[layer.name].locked = false 611: current_rule.arrow_group[layer.name].transform! Constants::DESCEND_T.inverse 612: current_rule.arrow_group[layer.name].locked = true 613: 614: current_rule.line_group[layer.name].locked = false 615: current_rule.line_group[layer.name].transform! Constants::DESCEND_T.inverse 616: current_rule.line_group[layer.name].locked = true 617: 618: current_rule.group_origin_left[layer.name].locked = false 619: current_rule.group_origin_left[layer.name].transform! Constants::DESCEND_T.inverse 620: current_rule.group_origin_left[layer.name].locked = true 621: 622: current_rule.group_origin_right[layer.name].locked = false 623: current_rule.group_origin_right[layer.name].transform! Constants::DESCEND_T.inverse 624: current_rule.group_origin_right[layer.name].locked = true 625: } 626: 627: idx += 1 628: end 629: execution.reset 630: project.refresh 631: end 632: else 633: UI.messagebox("You cannot delete all rules") 634: end 635: } 636: delete_rule_cmd.tooltip = "Delete rule" 637: delete_rule_cmd.small_icon = File.join(Constants::ICONS_DIR, "delete_rule.PNG") 638: delete_rule_cmd.large_icon = File.join(Constants::ICONS_DIR, "delete_rule.PNG") 639: toolbar.add_item delete_rule_cmd 640: 641: #Copy Rule command 642: copy_rule_cmd = UI::Command.new("copy_rule"){ 643: project = Shade.project 644: execution = Shade.project.execution 645: Sketchup.active_model.close_active 646: 647: prompts = ["Rule to copy: "] 648: default = ["1"] 649: 650: rule_list = ShadeUtils.create_rule_list() 651: list = [rule_list] 652: input = UI.inputbox prompts, default, list, "Rule to copy" 653: if input 654: n_rule = input[0].to_i-1 655: if n_rule < execution.grammar.rules.size 656: rule = execution.grammar.rules[n_rule] 657: size = execution.grammar.rules.size 658: 659: # Obtain shape transformations 660: t_left = rule.left.shape_transformation 661: t_right = rule.right.shape_transformation 662: 663: # Obtain the new shapes 664: left = rule.left.clone 665: right = rule.right.clone 666: 667: #Paint the rule 668: last_id = execution.grammar.rules[size-1].rule_id 669: 670: new_rule = ShadeUtils.paint_rule(last_id+1, left, right) 671: 672: #Transform the shapes 673: left.shape_transformation = t_left 674: right.shape_transformation = t_right 675: 676: execution.grammar.add_rule(new_rule) 677: project.refresh 678: else 679: UI.messagebox("Rule " + (n_rule+1).to_s + " doesn't exist") 680: end 681: end 682: } 683: copy_rule_cmd.tooltip = "Copy rule" 684: copy_rule_cmd.small_icon = File.join(Constants::ICONS_DIR, "copy_rule.PNG") 685: copy_rule_cmd.large_icon = File.join(Constants::ICONS_DIR, "copy_rule.PNG") 686: toolbar.add_item copy_rule_cmd 687: 688: #Add label command 689: add_label_cmd = UI::Command.new("add_label"){ 690: project = Shade.project 691: execution = Shade.project.execution 692: Sketchup.active_model.close_active 693: 694: prompts = ["Rule ID ", "Rule part ", "Color "] 695: default = ["1", Constants::LEFT, "Red"] 696: rule_list = ShadeUtils.create_rule_list() 697: list = [rule_list, "#{Constants::LEFT}|#{Constants::RIGHT}", "Red|Green|Blue|Yellow|White|Black"] 698: input = UI.inputbox prompts, default, list, "Add label to shape:" 699: if input 700: rule_idx = input[0].to_i - 1 701: rule = execution.grammar.rules[rule_idx] 702: if input[1] == Constants::LEFT 703: shape = rule.left 704: else 705: shape = rule.right 706: end 707: color = input[2] 708: add_label_tool = AddLabelTool.new(shape, color) 709: Sketchup.active_model.select_tool add_label_tool 710: end 711: } 712: add_label_cmd.tooltip = "Add label to shape" 713: add_label_cmd.small_icon = File.join(Constants::ICONS_DIR, "add_label.PNG") 714: add_label_cmd.large_icon = File.join(Constants::ICONS_DIR, "add_label.PNG") 715: toolbar.add_item add_label_cmd 716: 717: # Copy shape command 718: copy_shape_cmd = UI::Command.new("copy_shape"){ 719: project = Shade.project 720: execution = Shade.project.execution 721: Sketchup.active_model.close_active 722: 723: prompts = ["Origin Rule ID ", "Origin Rule part ", "Destiny Rule ID ", "Destiny rule part "] 724: default = ["1", Constants::LEFT, "1", Constants::RIGHT] 725: rule_list = ShadeUtils.create_rule_list() 726: list = [rule_list, "#{Constants::LEFT}|#{Constants::RIGHT}", rule_list, "#{Constants::LEFT}|#{Constants::RIGHT}"] 727: input = UI.inputbox prompts, default, list, "Copy shape:" 728: if input 729: origin_rule_idx = input[0].to_i - 1 730: origin_rule_part = input[1] 731: destiny_rule_idx = input[2].to_i - 1 732: destiny_rule_part = input[3] 733: ShadeUtils.copy_shape(origin_rule_idx, origin_rule_part, destiny_rule_idx, destiny_rule_part) 734: project.refresh 735: end 736: } 737: copy_shape_cmd.tooltip = "Copy shape" 738: copy_shape_cmd.small_icon = File.join(Constants::ICONS_DIR, "copy_shape.PNG") 739: copy_shape_cmd.large_icon = File.join(Constants::ICONS_DIR, "copy_shape.PNG") 740: toolbar.add_item copy_shape_cmd 741: 742: # Add shape box command 743: add_shape_box_command = UI::Command.new("add_shape_box"){ 744: Sketchup.active_model.close_active 745: prompts = ["Rule ID ", "Rule part "] 746: default = ["1", "Left"] 747: rule_list = ShadeUtils.create_rule_list() 748: list = [rule_list, "Left|Right"] 749: input = UI.inputbox prompts, default, list, "Choose shape:" 750: 751: if input 752: rule_idx = input[0].to_i - 1 753: # Transform the layout transformation of the shapes 754: t = Geom::Transformation.new 755: rule_idx.times do 756: t = Constants::DESCEND_T * t 757: end 758: 759: rule = Shade.project.execution.grammar.rules[rule_idx] 760: if input[1] == "Left" 761: t = Constants::LEFT_T * t 762: rule.alpha.erase 763: rule.alpha = ShadeUtils.create_default_left_shape 764: rule.alpha.layout_transformation = t 765: rule.alpha.paint 766: if ((rule_idx == 0) and (!Shade.project.execution.file_axiom)) 767: new_axiom = ShadeUtils.create_default_axiom 768: Shade.project.execution.grammar.axiom = new_axiom 769: Shade.project.execution.reset 770: end 771: else 772: t = Constants::RIGHT_T * t 773: rule.beta.erase 774: rule.beta= ShadeUtils.create_default_right_shape 775: rule.beta.layout_transformation = t 776: rule.beta.paint 777: end 778: end 779: } 780: add_shape_box_command.tooltip = "Add Shape Box" 781: add_shape_box_command.small_icon = File.join(Constants::ICONS_DIR, "create_shape_box.PNG") 782: add_shape_box_command.large_icon = File.join(Constants::ICONS_DIR, "create_shape_box.PNG") 783: toolbar.add_item add_shape_box_command 784: 785: toolbar.add_separator 786: 787: # Load shape command 788: load_shape_cmd = UI::Command.new("load_shape"){ 789: Sketchup.active_model.close_active 790: prompts = ["Rule ID ", "Rule part "] 791: default = ["1", "Left"] 792: rule_list = ShadeUtils.create_rule_list() 793: list = [rule_list, "Left|Right"] 794: input = UI.inputbox prompts, default, list, "Choose shape:" 795: if input 796: rule_idx = input[0].to_i - 1 797: rule = Shade.project.execution.grammar.rules[rule_idx] 798: if input[1] == "Left" 799: shape = rule.left 800: else 801: shape = rule.right 802: end 803: opened = false 804: while !opened 805: load_shape_path = UI.openpanel "Load Shape", "", "*.txt" 806: if load_shape_path 807: if ShadeUtils.get_extension(load_shape_path) == "txt" 808: begin 809: shape.load(load_shape_path) 810: opened = true 811: if ((rule_idx == 0) && (input[1] == "Left") && (!Shade.project.execution.file_axiom)) 812: # Add new axiom 813: new_axiom = LabelledShape.new(Array.new, Array.new) 814: Sketchup.active_model.layers.each { |layer| 815: new_axiom.p = shape.p.clone 816: new_axiom.s = shape.s.clone 817: } 818: Shade.project.execution.grammar.axiom = new_axiom 819: Shade.project.execution.reset 820: end 821: rescue LoadError => e 822: UI.messagebox(e.message) 823: rescue 824: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 825: end 826: else 827: UI.messagebox("Please choose a .txt file") 828: end 829: else 830: opened = true 831: end 832: end 833: end 834: } 835: load_shape_cmd.tooltip = "Load shape" 836: load_shape_cmd.small_icon = File.join(Constants::ICONS_DIR, "load_shape.PNG") 837: load_shape_cmd.large_icon = File.join(Constants::ICONS_DIR, "load_shape.PNG") 838: toolbar.add_item load_shape_cmd 839: 840: # Save shape command 841: save_shape_cmd = UI::Command.new("save_shape"){ 842: Sketchup.active_model.close_active 843: prompts = ["Rule ID ", "Rule part "] 844: default = ["1", "Left"] 845: rule_list = ShadeUtils.create_rule_list() 846: list = [rule_list, "Left|Right"] 847: input = UI.inputbox prompts, default, list, "Choose shape:" 848: if input 849: rule_idx = input[0].to_i - 1 850: rule = Shade.project.execution.grammar.rules[rule_idx] 851: if input[1] == "Left" 852: shape = rule.left 853: else 854: shape = rule.right 855: end 856: saved = false 857: while !saved 858: save_shape_path = UI.savepanel "Save Shape", "", "shape.txt" 859: if save_shape_path 860: if ShadeUtils.get_extension(save_shape_path) == "txt" 861: begin 862: shape.save(save_shape_path) 863: saved = true 864: rescue 865: UI.messagebox("The path you have chosen is not valid (maybe it has some special character?)") 866: end 867: else 868: UI.messagebox("Please save the shape as a .txt file") 869: end 870: else 871: saved = true 872: end 873: end 874: end 875: } 876: save_shape_cmd.tooltip = "Save shape" 877: save_shape_cmd.small_icon = File.join(Constants::ICONS_DIR, "save_shape.PNG") 878: save_shape_cmd.large_icon = File.join(Constants::ICONS_DIR, "save_shape.PNG") 879: toolbar.add_item save_shape_cmd 880: 881: toolbar.add_separator 882: 883: # About command 884: about_cmd = UI::Command.new("about"){ 885: UI.messagebox("ShaDe v#{Constants::VERSION}\nAll rights reserved\nFor research use only \n(c) Manuela Ruiz Montiel and Universidad de Malaga") 886: } 887: about_cmd.tooltip = "About" 888: about_cmd.small_icon = File.join(Constants::ICONS_DIR, "about.PNG") 889: about_cmd.large_icon = File.join(Constants::ICONS_DIR, "about.PNG") 890: toolbar.add_item about_cmd 891: 892: toolbar.show 893: end
Deletes all the files inside temp folder
# File lib/interfaces/guitools.rb, line 227 227: def delete_temp_files() 228: dir = Dir.new("#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}") 229: dir.each { |file_name| 230: if file_name == '.' or file_name == '..' then next 231: else File.delete("#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/#{file_name}") 232: end 233: } 234: end
Loads the temp files
# File lib/interfaces/guitools.rb, line 210 210: def load_temp_files() 211: execution = Shade.project.execution 212: 213: #STEP 1: Load execution history 214: history_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}" 215: history_directory.gsub!("/", "\\") 216: execution.load_execution_history(history_directory) 217: 218: #STEP 1: Load current shape 219: current_shape_path = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/current_shape.txt" 220: current_shape_path.gsub!("/", "\\") 221: execution.current_shape.load(current_shape_path) 222: execution.current_shape.refresh 223: execution.current_shape.create_pi 224: end
Saves the project, the current shape and the execution history
# File lib/interfaces/guitools.rb, line 190 190: def save_temp_files() 191: project = Shade.project 192: 193: #STEP 1: Save project 194: project_path = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/project.txt" 195: project_path.gsub!("/", "\\") 196: project.save(project_path, true) 197: 198: #STEP 2: Save current shape 199: current_shape_path = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}/current_shape.txt" 200: current_shape_path.gsub!("/", "\\") 201: project.execution.current_shape.save(current_shape_path) 202: 203: #STEP 2: Save execution history 204: history_directory = "#{File.dirname(__FILE__)}/#{Constants::TEMP_DIR}" 205: history_directory.gsub!("/", "\\") 206: project.execution.save_execution_history(history_directory) 207: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.