Author | Manuela Ruiz (mruiz@lcc.uma.es) |
This class represents a LabelledShape, that is, a shape with any number of labels
edges | list of edges |
points_and_materials | list of pairs (point, material) |
Initializes the hashes of maximal lines and labelled points, associated with layer 0
# File lib/geometry.rb, line 611 611: def initialize(edges, points_and_materials) 612: if !@s 613: @s = Hash.new(nil) 614: if Shade.using_sketchup 615: Sketchup.active_model.layers.each { |layer| 616: @s[layer.name] = LinearLinkedList.new 617: } 618: else 619: @s["Layer0"] = LinearLinkedList.new 620: end 621: end 622: if !@p 623: @p = Hash.new(nil) 624: if Shade.using_sketchup 625: Sketchup.active_model.layers.each { |layer| 626: @p[layer.name] = LinearLinkedList.new 627: } 628: else 629: @p["Layer0"] = LinearLinkedList.new 630: end 631: end 632: edges.each { |e| 633: segment = Segment.new(OrderedPoint.new(e.start.position), OrderedPoint.new(e.end.position)) 634: segment_list = LinearLinkedList.new 635: 636: if @s["Layer0"].kind_of? LinearLinkedList 637: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil) 638: else 639: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list) 640: end 641: 642: inserted_node = @s["Layer0"].insert_node(node) #Insert the node corresponding to the line descriptor of the segment 643: 644: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines 645: new_segment_list = LinearLinkedList.new 646: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil) 647: new_segment_list.insert_node(segment_node) 648: 649: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS) 650: } 651: 652: #Compound the label lists 653: points_and_materials.each { |pair| 654: point = OrderedPoint.new(pair[0]) 655: label = Label.new(pair[1]) 656: point_list = LinearLinkedList.new 657: 658: if @p["Layer0"].kind_of? LinearLinkedList 659: node = LinearLinkedListNode.new(label, point_list, nil) 660: else 661: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list) 662: end 663: 664: inserted_node = @p["Layer0"].insert_node(node) #Insert the node corresponding to the label of the point 665: 666: point_node = LinearLinkedListNode.new(point, nil, nil) 667: inserted_node.list.insert_node(point_node) #Insert the point node 668: } 669: recompute_intersection_points 670: end
point | a Point object |
value | the name of the label value |
layer_name | the name of the layer on which the label is going to be added |
Adds a label to the shape in the position determined by point, with the specified value and in the specified layer
# File lib/geometry.rb, line 731 731: def add_label(point, value, layer_name) 732: if @p[layer_name] 733: label = Label.new(value) 734: point_list = LinearLinkedList.new 735: 736: node = LinearLinkedListNode.new(label, point_list, nil) 737: 738: inserted_node = @p[layer_name].insert_node(node) #Insert the node corresponding to the label of the point 739: 740: point_node = LinearLinkedListNode.new(OrderedPoint.new(point), nil, nil) 741: inserted_node.list.insert_node(point_node) #Insert the point node 742: end 743: end
returns | the hash code for this labelled shape |
# File lib/geometry.rb, line 1581 1581: def hash 1582: return [@s["Layer0"].hash, @p["Layer0"].hash].hash 1583: end
path | path to load the shape from |
Loads the shape in the specified path
# File lib/geometry.rb, line 1326 1326: def load(path) 1327: 1328: if Shade.using_sketchup 1329: extension = ShadeUtils.get_extension(path) 1330: 1331: if extension == "skp" 1332: 1333: #We remove everything 1334: rules = Shade.project.execution.grammar.rules 1335: rules.each {|rule| 1336: rule.erase 1337: } 1338: Shade.project.execution.current_shape.erase 1339: Sketchup.active_model.active_entities.erase_entities(Sketchup.active_model.active_entities.to_a) 1340: 1341: path = path.tr("\\","/") 1342: Sketchup.active_model.save("trash.skp") 1343: Sketchup.open_file(path) #A group is loaded 1344: File.delete("trash.skp") 1345: entities = Sketchup.active_model.entities[0].entities 1346: 1347: edges = Array.new 1348: points_and_materials = Array.new 1349: 1350: entities.each { |e| 1351: if e.kind_of? Sketchup::Edge 1352: edges.push e 1353: elsif e.kind_of? Sketchup::Group 1354: e.entities.each { |ge| 1355: if ge.kind_of? Sketchup::ConstructionPoint 1356: points_and_materials.push [ge.position, e.material] 1357: end 1358: } 1359: 1360: end 1361: } 1362: 1363: self.refresh_from_info(edges, points_and_materials) 1364: 1365: Sketchup.active_model.active_entities.erase_entities(Sketchup.active_model.active_entities.to_a) 1366: 1367: #We repaint everything 1368: ShadeUtils.prepare_canvas(false) 1369: rules.each {|rule| 1370: rule.repaint 1371: } 1372: Shade.project.execution.current_shape.paint 1373: elsif extension == "txt" 1374: File.open(path, 'r') do |f| 1375: layer_found = false 1376: while line = f.gets 1377: line_a1 = line.split(":") 1378: if line_a1[0].strip == "S" #Segment 1379: if !layer_found 1380: if self.kind_of? CurrentLabelledShape 1381: @s["Layer0"] = BalancedBinaryTree.new 1382: else 1383: @s["Layer0"] = LinearLinkedList.new 1384: end 1385: @p["Layer0"] = LinearLinkedList.new 1386: layer_name = "Layer0" 1387: layer_found = true 1388: end 1389: line_a = line_a1[1].split 1390: segment = Segment.new(OrderedPoint.new(Geom::Point3d.new(line_a[0].to_f.m, line_a[1].to_f.m, 0)), OrderedPoint.new(Geom::Point3d.new(line_a[2].to_f.m, line_a[3].to_f.m, 0))) 1391: segment_list = LinearLinkedList.new 1392: 1393: if @s[layer_name].kind_of? LinearLinkedList 1394: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil) 1395: else 1396: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list) 1397: end 1398: 1399: inserted_node = @s[layer_name].insert_node(node) #Insert the node corresponding to the line descriptor of the segment 1400: 1401: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines 1402: new_segment_list = LinearLinkedList.new 1403: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil) 1404: new_segment_list.insert_node(segment_node) 1405: 1406: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS) 1407: 1408: elsif line_a1[0].strip == "L" #Label 1409: if !layer_found 1410: if self.kind_of? CurrentLabelledShape 1411: @s["Layer0"] = BalancedBinaryTree.new 1412: else 1413: @s["Layer0"] = LinearLinkedList.new 1414: end 1415: @p["Layer0"] = LinearLinkedList.new 1416: layer_name = "Layer0" 1417: layer_found = true 1418: end 1419: line_a = line_a1[1].split 1420: color = line_a[2] 1421: raise LoadError, "The color name: #{color} of shape in file #{path} is not recognized" unless Constants::RECOGNIZED_COLORS.include? color 1422: 1423: label = Label.new(line_a[2]) 1424: point = OrderedPoint.new(Geom::Point3d.new(line_a[0].to_f.m, line_a[1].to_f.m, 0)) 1425: point_list = LinearLinkedList.new 1426: 1427: if @p[layer_name].kind_of? LinearLinkedList 1428: node = LinearLinkedListNode.new(label, point_list, nil) 1429: else 1430: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list) 1431: end 1432: 1433: inserted_node = @p[layer_name].insert_node(node) #Insert the node corresponding to the label of the point 1434: 1435: point_node = LinearLinkedListNode.new(point, nil, nil) 1436: inserted_node.list.insert_node(point_node) #Insert the point node 1437: elsif line_a1[0].strip == "LAYER" #Layer 1438: layer_name = line_a1[1].strip 1439: if self.kind_of? CurrentLabelledShape 1440: @s[layer_name] = BalancedBinaryTree.new 1441: else 1442: @s[layer_name] = LinearLinkedList.new 1443: end 1444: @p[layer_name] = LinearLinkedList.new 1445: layer_found = true 1446: end 1447: end 1448: end 1449: recompute_intersection_points 1450: #paint 1451: end 1452: else 1453: extension = ShadeUtils.get_extension(path) 1454: 1455: if extension == "txt" 1456: layer_name = "Layer0" 1457: File.open(path, 'r') do |f| 1458: layer_found = false 1459: while line = f.gets 1460: line_a1 = line.split(":") 1461: if line_a1[0].strip == "S" #Segment 1462: if !layer_found 1463: if self.kind_of? CurrentLabelledShape 1464: @s["Layer0"] = BalancedBinaryTree.new 1465: else 1466: @s["Layer0"] = LinearLinkedList.new 1467: end 1468: @p["Layer0"] = LinearLinkedList.new 1469: layer_name = "Layer0" 1470: layer_found = true 1471: end 1472: line_a = line_a1[1].split 1473: segment = Segment.new(OrderedPoint.new(Point.new(line_a[0].to_f, line_a[1].to_f, 0)), OrderedPoint.new(Point.new(line_a[2].to_f, line_a[3].to_f, 0))) 1474: segment_list = LinearLinkedList.new 1475: 1476: if @s[layer_name].kind_of? LinearLinkedList 1477: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil) 1478: else 1479: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list) 1480: end 1481: 1482: inserted_node = @s[layer_name].insert_node(node) #Insert the node corresponding to the line descriptor of the segment 1483: 1484: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines 1485: new_segment_list = LinearLinkedList.new 1486: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil) 1487: new_segment_list.insert_node(segment_node) 1488: 1489: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS) 1490: 1491: elsif line_a1[0].strip == "L" #Label 1492: if !layer_found 1493: if self.kind_of? CurrentLabelledShape 1494: @s["Layer0"] = BalancedBinaryTree.new 1495: else 1496: @s["Layer0"] = LinearLinkedList.new 1497: end 1498: @p["Layer0"] = LinearLinkedList.new 1499: layer_name = "Layer0" 1500: layer_found = true 1501: end 1502: line_a = line_a1[1].split 1503: color = line_a[2] 1504: raise LoadError, "The color name: #{color} of shape in file #{path} is not recognized" unless Constants::RECOGNIZED_COLORS.include? color 1505: label = Label.new(line_a[2]) 1506: point = OrderedPoint.new(Point.new(line_a[0].to_f, line_a[1].to_f, 0)) 1507: point_list = LinearLinkedList.new 1508: 1509: if @p[layer_name].kind_of? LinearLinkedList 1510: node = LinearLinkedListNode.new(label, point_list, nil) 1511: else 1512: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list) 1513: end 1514: 1515: inserted_node = @p[layer_name].insert_node(node) #Insert the node corresponding to the label of the point 1516: 1517: point_node = LinearLinkedListNode.new(point, nil, nil) 1518: inserted_node.list.insert_node(point_node) #Insert the point node 1519: elsif line_a1[0].strip == "LAYER" #Layer 1520: layer_name = line_a1[1].strip 1521: if self.kind_of? CurrentLabelledShape 1522: @s[layer_name] = BalancedBinaryTree.new 1523: else 1524: @s[layer_name] = LinearLinkedList.new 1525: end 1526: @p[layer_name] = LinearLinkedList.new 1527: layer_found = true 1528: end 1529: end 1530: end 1531: recompute_intersection_points 1532: #paint 1533: end 1534: end 1535: 1536: end
list1: a LinearLinkedList of Segments or Points list2: a LinearLinkedList of Segments or Points
op_rel_type | the operation or relation to perform. One of the following: Constants::UNION, Constants::INTERSECTION, Constants::DIFFERENCE, |
Constants::SUBSHAPE, Constants::EQUAL
c | Constants::SEGMENT if segments are affected, Constants::POINTS if points are affected. |
returns::true iff the specified relation (subshape or equal) holds (or false if it does not hold). In case it is an union or difference operation, it just overwrites list1 with the resulting list of the operation. In case it is an intersection, it returns a new segment list.
# File lib/geometry.rb, line 952 952: def op_rel(list1, list2, op_rel_type, c) 953: if (c == Constants::SEGMENTS) 954: if (op_rel_type == Constants::UNION) 955: #Step 0 956: working_line_node = list2.first 957: linej_node = list1.first 958: if !list1.empty? 959: #Step 1 960: step1_union(list1, list2, working_line_node, linej_node) 961: else 962: #Step 8 963: #There may still be some unexamined lines in line2. Copy all the unexamined lines in line2 in their order, and attach them 964: #to the end of list list1 965: step8_union(list1, list2, working_line_node, linej_node) 966: end 967: elsif (op_rel_type == Constants::DIFFERENCE) 968: #Step 0 969: if !list1.empty? 970: #step 1 971: working_line_node = list2.first 972: linej_node = list1.first 973: step1_difference(list1, list2, working_line_node, linej_node) 974: end 975: elsif (op_rel_type == Constants::INTERSECTION) 976: if !list1.empty? 977: #Step 0 978: working_line_node = list2.first 979: linej_node = list1.first 980: list3 = LinearLinkedList.new 981: #step 1 982: step1_intersection(list1, list2, list3, working_line, linej) 983: end 984: elsif (op_rel_type == Constants::SUBSHAPE) 985: #step 0 986: flag = true 987: if !list1.empty? 988: #step 1 989: working_line_node = list2.first 990: linej_node = list1.first 991: flag = step1_subshape(flag, list1, list2, working_line_node, linej_node) 992: else 993: flag = (list2.empty?) 994: end 995: elsif (op_rel_type == Constants::EQUAL) 996: flag = (list1 == list2) 997: end 998: elsif (c == Constants::POINTS) 999: if (op_rel_type == Constants::UNION) 1000: list2.reset_iterator 1001: while n = list2.get_next 1002: point = n.key 1003: list1.insert_node(LinearLinkedListNode.new(point.clone, nil, nil)) 1004: end 1005: elsif (op_rel_type == Constants::DIFFERENCE) 1006: list2.reset_iterator 1007: while n = list2.get_next 1008: point = n.key 1009: list1.delete_node(point) 1010: end 1011: elsif (op_rel_type == Constants::INTERSECTION) 1012: list3 = LinearLinkedList.new 1013: list2.reset_iterator 1014: while n = list2.get_next 1015: point = n.key 1016: if list1.get_node(point) 1017: list3.insert_node(LinearLinkedListNode.new(point.clone, nil, nil)) 1018: end 1019: end 1020: elsif (op_rel_type == Constants::SUBSHAPE) 1021: flag = true 1022: list2.reset_iterator 1023: while (flag && n = list2.get_next) 1024: point = n.key 1025: flag = list1.get_node(point) 1026: if !flag 1027: flag = false 1028: else 1029: flag = true 1030: end 1031: end 1032: elsif (op_rel_type == Constants::EQUAL) 1033: flag = (list1 == list2) 1034: end 1035: end 1036: 1037: if (op_rel_type == Constants::INTERSECTION) 1038: return list3 1039: elsif (op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL) 1040: return flag 1041: end 1042: end
Paints the view of the shape
# File lib/geometry.rb, line 1539 1539: def paint() 1540: if Shade.using_sketchup 1541: entities = Sketchup.active_model.entities 1542: 1543: layers = Sketchup.active_model.layers 1544: 1545: @s.each_key { |layer_name| 1546: @s[layer.name].reset_iterator 1547: while (node = @s[layer.name].get_next) 1548: node.list.reset_iterator 1549: while (segment_node = node.list.get_next) 1550: entities.add_edges segment_node.key.tail.point, segment_node.key.head.point 1551: end 1552: end 1553: } 1554: 1555: @p.each_key { |layer_name| 1556: @p[layer.name].reset_iterator 1557: while (node = @p[layer.name].get_next) 1558: label = node.key 1559: node.list.reset_iterator 1560: while (labelled_point_node = node.list.get_next) 1561: if !(label.value==Constants::INTERSECTION_LABEL) #The label is a coloured circle 1562: label_group = entities.add_group 1563: 1564: # Add circle 1565: edges = label_group.entities.add_circle labelled_point_node.key.point, Constants::LABEL_VECTOR, Shade.label_radius 1566: #Add construction point in order to locate the center later 1567: label_group.entities.add_cpoint labelled_point_node.key.point 1568: #Add face 1569: face = label_group.entities.add_face edges 1570: #Give color to the face 1571: label_group.material = label.value 1572: end 1573: end 1574: end 1575: 1576: } 1577: end 1578: end
Recompute the intersection points of the shape
# File lib/geometry.rb, line 862 862: def recompute_intersection_points(testing = false) 863: 864: @s.each_key { |layer_name| 865: #First, we remove the old intersection points, if any 866: @p[layer_name].delete_node(Label.new(Constants::INTERSECTION_LABEL)) 867: 868: s_array = @s[layer_name].to_array 869: 870: #Second, we obtain the nodes of the maximal lines in order 871: @s[layer_name].reset_iterator 872: i = 0 873: while (node = @s[layer_name].get_next) 874: j = i 875: #Obtain next_node without breaking the iterator 876: while (j < s_array.size) 877: #puts "Comparing #{i} line with #{j} line" 878: next_node = s_array[j] 879: if !(next_node.key.sine == node.key.sine) #If line descriptors are not parallel... 880: current_segment_node = node.list.first 881: found1 = false 882: #While there are segments in node and the intersection is not found 883: while (current_segment_node && !found1) 884: current_segment = current_segment_node.key 885: segment_node = next_node.list.first 886: found2 = false 887: #While there are segments in next_node and the intersection is not found 888: while (segment_node && !found1 && !found2) 889: segment = segment_node.key 890: #Calculate ua 891: #Numerator 892: uan = (((segment.head.x - segment.tail.x)*(current_segment.tail.y - segment.tail.y)) - ((segment.head.y - segment.tail.y)*(current_segment.tail.x - segment.tail.x))) 893: #Denominator 894: uad = (((segment.head.y - segment.tail.y)*(current_segment.head.x - current_segment.tail.x)) - ((segment.head.x - segment.tail.x)*(current_segment.head.y - current_segment.tail.y))) 895: #The denominator is not going to be zero since the studied lines are not parallel neither coincident 896: ua = uan/uad 897: 898: #Calculate ub 899: #Numerator 900: ubn = (((current_segment.head.x - current_segment.tail.x)*(current_segment.tail.y - segment.tail.y)) - ((current_segment.head.y - current_segment.tail.y)*(current_segment.tail.x - segment.tail.x))) 901: #Denominator 902: ubd = uad 903: #The denominator is not going to be zero since the studied lines are not parallel neither coincident 904: ub = ubn/ubd 905: #if testing 906: #puts "ua: #{ua}, ub: #{ub}" 907: #end 908: if (ua > (1 + Constants::EPSILON)) #The current_segment does not intersect with the next_node line descriptor. Maybe some higher segment does intersect 909: found2 = true 910: elsif (ua < (0 - Constants::EPSILON)) 911: found1 = true #We can stop searching this pair of lines, since there is not any pair of segments that intersect 912: elsif ((((0 - Constants::EPSILON) <= ub) && (ub <= (1 + Constants::EPSILON))) && (((0 - Constants::EPSILON) <= ua) && (ua <= (1 + Constants::EPSILON)))) #We have found the intersection 913: found1 = true #We can stop searching this pair of lines 914: label = Label.new(Constants::INTERSECTION_LABEL) 915: point_list = LinearLinkedList.new 916: if @p[layer_name].kind_of? LinearLinkedList 917: label_node = LinearLinkedListNode.new(label, point_list, nil) 918: else 919: label_node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list) 920: end 921: 922: inserted_node = @p[layer_name].insert_node(label_node) #Insert the node corresponding to the label of the point 923: 924: #Calculate the point 925: x = current_segment.tail.x + (ua * (current_segment.head.x - current_segment.tail.x)) 926: y = current_segment.tail.y + (ua * (current_segment.head.y - current_segment.tail.y)) 927: point = Point.new(x,y,0) 928: point_node = LinearLinkedListNode.new(OrderedPoint.new(point), nil, nil) 929: inserted_node.list.insert_node(point_node) #Insert the point node 930: #puts "point inserted: #{point.x}, #{point.y}" 931: end 932: segment_node = segment_node._next 933: end 934: current_segment_node = current_segment_node._next 935: end 936: end 937: j+=1 938: end 939: i+=1 940: end 941: } 942: end
edges | an array of SketchUp Edges |
points_and_materials | an array of pairs [Point3d, Material], both of them are classes of SketchUp |
layer | name of the layer that is affected |
Refresh the internal representation of the shape according to the current SketchUp canvas content inside the group of the shape
# File lib/geometry.rb, line 677 677: def refresh_from_info(edges, points_and_materials, layer) 678: if (@s[layer] and @p[layer]) 679: if @s[layer].kind_of? BalancedBinaryTree 680: @s[layer] = BalancedBinaryTree.new 681: else 682: @s[layer] = LinearLinkedList.new 683: end 684: @p[layer] = LinearLinkedList.new 685: edges.each { |e| 686: segment = Segment.new(OrderedPoint.new(e.start.position), OrderedPoint.new(e.end.position)) 687: segment_list = LinearLinkedList.new 688: 689: if @s[layer].kind_of? LinearLinkedList 690: node = LinearLinkedListNode.new(segment.line_descriptor, segment_list, nil) 691: else 692: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, segment.line_descriptor, segment_list) 693: end 694: 695: inserted_node = @s[layer].insert_node(node) #Insert the node corresponding to the line descriptor of the segment 696: 697: #We create an auxiliar list filled with the new segment to add, in order to make the union and obtain the maximal lines 698: new_segment_list = LinearLinkedList.new 699: segment_node = LinearLinkedListNode.new(segment.clone, nil, nil) 700: new_segment_list.insert_node(segment_node) 701: 702: op_rel(inserted_node.list, new_segment_list, Constants::UNION, Constants::SEGMENTS) 703: } 704: 705: #Compound the label lists 706: points_and_materials.each { |pair| 707: point = OrderedPoint.new(pair[0]) 708: label = Label.new(pair[1]) 709: point_list = LinearLinkedList.new 710: 711: if @p[layer].kind_of? LinearLinkedList 712: node = LinearLinkedListNode.new(label, point_list, nil) 713: else 714: node = BalancedBinaryTreeNode.new(Constants::BALANCED, nil, nil, label, point_list) 715: end 716: 717: inserted_node = @p[layer].insert_node(node) #Insert the node corresponding to the label of the point 718: 719: point_node = LinearLinkedListNode.new(point, nil, nil) 720: inserted_node.list.insert_node(point_node) #Insert the point node 721: } 722: recompute_intersection_points 723: end 724: end
path | path to save the shape in |
Saves the shape in the specified path
# File lib/geometry.rb, line 1246 1246: def save(path) 1247: 1248: if Shade.using_sketchup 1249: extension = ShadeUtils.get_extension(path) 1250: 1251: if extension == "skp" 1252: rules = Shade.project.execution.grammar.rules 1253: rules.each {|rule| 1254: rule.erase 1255: } 1256: Sketchup.active_model.entities 1257: Shade.project.execution.current_shape.erase 1258: 1259: Sketchup.active_model.active_entities.erase_entities(Sketchup.active_model.active_entities.to_a) 1260: 1261: self.paint 1262: 1263: path = path.tr("\\","/") 1264: Sketchup.active_model.save(path) 1265: 1266: ShadeUtils.prepare_canvas(false) 1267: rules.each {|rule| 1268: rule.repaint 1269: } 1270: Shade.project.execution.current_shape.paint 1271: elsif extension == "txt" 1272: File.open(path, 'w') do |f| 1273: Sketchup.active_model.layers.each { |layer| 1274: f.write("LAYER: #{layer.name}\n") 1275: @s[layer.name].reset_iterator 1276: while s_node = @s[layer.name].get_next 1277: s_node.list.reset_iterator 1278: while s = s_node.list.get_next 1279: f.write("S: #{s.key.tail.x.to_f.to_m} #{s.key.tail.y.to_f.to_m} #{s.key.head.x.to_f.to_m} #{s.key.head.y.to_f.to_m}\n") 1280: end 1281: end 1282: @p[layer.name].reset_iterator 1283: while l_node = @p[layer.name].get_next 1284: if !(l_node.key.value == Constants::INTERSECTION_LABEL) 1285: l_node.list.reset_iterator 1286: while l = l_node.list.get_next 1287: f.write("L: #{l.key.x.to_f.to_m} #{l.key.y.to_f.to_m} #{l_node.key.value}\n") 1288: end 1289: end 1290: end 1291: } 1292: end 1293: end 1294: else 1295: extension = ShadeUtils.get_extension(path) 1296: if extension == "txt" 1297: File.open(path, 'w') do |f| 1298: @s.each_key { |layer_name| 1299: f.write("LAYER: #{layer_name}\n") 1300: @s[layer_name].reset_iterator 1301: while s_node = @s[layer_name].get_next 1302: s_node.list.reset_iterator 1303: while s = s_node.list.get_next 1304: f.write("S: #{s.key.tail.x.to_f} #{s.key.tail.y.to_f} #{s.key.head.x.to_f} #{s.key.head.y.to_f}\n") 1305: end 1306: end 1307: @p[layer_name].reset_iterator 1308: while l_node = @p[layer_name].get_next 1309: if !(l_node.key.value == Constants::INTERSECTION_LABEL) 1310: l_node.list.reset_iterator 1311: while l = l_node.list.get_next 1312: f.write("L: #{l.key.x.to_f} #{l.key.y.to_f} #{l_node.key.value}\n") 1313: end 1314: end 1315: end 1316: } 1317: end 1318: end 1319: end 1320: 1321: end
other_shape | another LabelledShape |
op_rel_type | the operation or relation to perform. One of the following: Constants::UNION, Constants::INTERSECTION, Constants::DIFFERENCE, |
Constants::SUBSHAPE, Constants::EQUAL
c | Constants::SEGMENTS if segments are affected, Constants::POINTS if points are affected. |
returns | true iff the specified relation (subshape or equal) holds (or false if it does not hold). In case it is an operation, |
it just overwrites this shape with the resulting shape of the operation OR returns another shape in case it is an intersection
# File lib/geometry.rb, line 752 752: def shape_expression(other_shape, op_rel_type, c, print = false) 753: 754: global_flag = true 755: 756: result = LabelledShape.new(Array.new, Array.new) 757: if (c == Constants::SEGMENTS) 758: c1_hash = @s 759: c2_hash = other_shape.s 760: c3_hash = result.s 761: elsif (c==Constants::POINTS) 762: c1_hash = @p 763: c2_hash = other_shape.p 764: c3_hash = result.p 765: end 766: 767: c2_hash.each_key { |layer_name| 768: 769: flag = true 770: #Initialization 771: 772: c1 = c1_hash[layer_name] 773: c2 = c2_hash[layer_name] 774: c3 = c3_hash[layer_name] 775: 776: #NOTE: if c2 is empty, then the subshape relation DOES hold 777: 778: if (!c1) 779: if (c == Constants::SEGMENTS) 780: if self.kind_of? CurrentLabelledShape 781: c1 = BalancedBinaryTree.new 782: c1_hash[layer_name] = c1 783: else 784: c1 = LinearLinkedList.new 785: c1_hash[layer_name] = c1 786: end 787: else 788: c1 = LinearLinkedList.new 789: c1_hash[layer_name] = c1 790: end 791: end 792: if (!c2) 793: if (c == Constants::SEGMENTS) 794: if self.kind_of? CurrentLabelledShape 795: c2 = BalancedBinaryTree.new 796: c2_hash[layer_name] = c2 797: else 798: c2 = LinearLinkedList.new 799: c2_hash[layer_name] = c2 800: end 801: else 802: c2 = LinearLinkedList.new 803: c2_hash[layer_name] = c2 804: end 805: end 806: c2.reset_iterator 807: while ((v = c2.get_next) && flag) 808: if (!(v.key == Label.new(Constants::INTERSECTION_LABEL))) #we do not need to compare intersection points 809: u = c1.get_node(v.key) 810: if u #Matching keys found. Perform the appropiate action 811: if (op_rel_type == Constants::UNION) || (op_rel_type == Constants::INTERSECTION) || (op_rel_type == Constants::DIFFERENCE) 812: if (op_rel_type == Constants::UNION) || (op_rel_type == Constants::DIFFERENCE) 813: op_rel(u.list, v.list, op_rel_type, c) 814: else 815: result_list = op_rel(u.list, v.list, op_rel_type, c) 816: node = LinearLinkedListNode.new(v.key.clone, result_list, nil) 817: c3.insert_node node 818: end 819: if u.list.empty? 820: c1.delete_node(u.key) 821: flag = !c1.empty? #CHECK: es esto equivalente al alg. de krishnamurti?? 822: end 823: elsif (op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL) 824: flag = op_rel(u.list, v.list, op_rel_type, c) 825: end 826: else #There is no node with the same key value as v 827: if op_rel_type == Constants::UNION 828: if c1.kind_of? BalancedBinaryTree 829: new_node = BalancedBinaryTreeNode.new(0,nil,nil,v.key.clone, v.list.clone) 830: else 831: new_node = LinearLinkedListNode.new(v.key.clone, v.list.clone, nil) 832: end 833: c1.insert_node(new_node) 834: elsif (op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL) 835: flag = false 836: end 837: end 838: end 839: end 840: 841: if (c == Constants::SEGMENTS) 842: #puts "#{layer_name}: #{flag}" 843: end 844: 845: global_flag = (global_flag and flag) 846: } 847: 848: #Finishing touches 849: if ((op_rel_type == Constants::SUBSHAPE) || (op_rel_type == Constants::EQUAL)) 850: return global_flag 851: elsif (op_rel_type == Constants::INTERSECTION) 852: if (c == Constants::SEGMENTS) 853: result.recompute_intersection_points 854: end 855: return result 856: elsif (c == Constants::SEGMENTS) 857: self.recompute_intersection_points 858: end 859: end
First step of the difference algorithm of Krishnamurti
# File lib/geometry.rb, line 1111 1111: def step1_difference(list1, list2, working_line_node, linej_node) 1112: if (linej_node.key.tail < working_line_node.key.head) 1113: #step 3 1114: if (working_line_node.key.tail < linej_node.key.head) 1115: #step 5 1116: lineA = Segment.new(linej_node.key.tail, working_line_node.key.tail) 1117: lineB = Segment.new(working_line_node.key.head, linej_node.key.head) 1118: if (linej_node.key.tail < working_line_node.key.tail) && (linej_node.key.head <= working_line_node.key.head) 1119: linej_node.key = lineA.clone 1120: step4_difference(list1, list2, working_line_node, linej_node) 1121: elsif (working_line_node.key.tail <= linej_node.key.tail) && (working_line_node.key.head < linej_node.key.head) 1122: linej_node.key = lineB.clone 1123: step2_difference(list1, list2, working_line_node, linej_node) 1124: elsif (linej_node.key.tail < working_line_node.key.tail) && (working_line_node.key.head < linej_node.key.head) 1125: linej_node.key = lineB.clone 1126: list1.insert_node(LinearLinkedListNode.new(lineA.clone, nil, nil)) 1127: step2_difference(list1, list2, working_line_node, linej_node) 1128: elsif (working_line_node.key.tail <= linej_node.key.tail) && (linej_node.key.head <= working_line_node.key.head) 1129: list1.delete_node(linej_node.key) 1130: step4_difference(list1, list2, working_line_node, linej_node) 1131: end 1132: else 1133: #step 4 1134: step4_difference(list1, list2, working_line_node, linej_node) 1135: end 1136: else 1137: #step 2 1138: step2_difference(list1, list2, working_line_node, linej_node) 1139: end 1140: end
First step of the intersection algorithm of Krishnamurti
# File lib/geometry.rb, line 1163 1163: def step1_intersection(list1, list2, list3, working_line_node, linej_node) 1164: if (linej_node.key.tail < working_line_node.key.head) 1165: #step 3 1166: if (working_line_node.key.tail < linej_node.key.head) 1167: #step 5 1168: #step 5.1 1169: if (linej_node.key.tail < working_line_node.key.tail) 1170: new_tail = working_line_node.key.tail 1171: else 1172: new_tail = linej_node.key.tail 1173: end 1174: if (working_line_node.key.head < linej_node.key.head) || (linej_node.key.head == working_line_node.key.head) 1175: #step 5.2 1176: new_head = working_line_node.key.head 1177: segmentk = Segment.new(new_tail, new_head) 1178: list3.insert_node(LinearLinkedListNode.new(segmentk, nil, nil)) 1179: step2_intersection(list1, list2, list3, working_line_node, linej_node) 1180: else 1181: #step 5.3 1182: new_head = linej_node.key.head 1183: segmentk = Segment.new(new_tail, new_head) 1184: list3.insert_node(LinearLinkedListNode.new(segmentk, nil, nil)) 1185: step4_intersection(list1, list2, list3, working_line_node, linej_node) 1186: end 1187: else 1188: #step 4 1189: step4_intersection(list1, list2, list3, working_line_node, linej_node) 1190: end 1191: else 1192: #step 2 1193: step2_intersection(list1, list2, list3, working_line_node, linej_node) 1194: end 1195: end
First step of the subshape algorithm of Krishnamurti
# File lib/geometry.rb, line 1214 1214: def step1_subshape(flag, list1, list2, working_line_node, linej_node) 1215: if (working_line_node.key.tail < linej_node.key.head) 1216: #step3 1217: if (linej_node.key.tail < working_line_node.key.head) 1218: #step4 1219: if ((working_line_node.key.tail >= linej_node.key.tail) && (working_line_node.key.head <= linej_node.key.head)) 1220: #step 5 1221: if (working_line_node._next) 1222: working_line_node = working_line_node._next 1223: flag = step1_subshape(flag, list1, list2, working_line_node, linej_node) 1224: end 1225: else 1226: flag = false 1227: end 1228: else 1229: flag = false 1230: end 1231: else 1232: #step2 1233: if (linej_node._next) 1234: linej_node = linej_node._next 1235: flag = step1_subshape(flag, list1, list2, working_line_node, linej_node) 1236: else 1237: flag = false 1238: end 1239: end 1240: return flag 1241: end
First step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1045 1045: def step1_union(list1, list2, working_line_node, linej_node) 1046: if (linej_node.key.tail <= working_line_node.key.head) 1047: #Step 3 1048: if (working_line_node.key.tail <= linej_node.key.head) 1049: #Step 5 1050: if (working_line_node.key.tail < linej_node.key.tail) 1051: linej_node.key.tail = working_line_node.key.tail.clone 1052: else 1053: working_line_node.key.tail = linej_node.key.tail.clone 1054: end 1055: #Step 6 1056: if (linej_node.key.head >= working_line_node.key.head) 1057: #GOTO step 2 1058: step2_union(list1, list2, working_line_node, linej_node) 1059: else 1060: list1.delete_node(linej_node.key) 1061: #Step 4 1062: step4_union(list1, list2, working_line_node, linej_node) 1063: end 1064: 1065: else 1066: #Step 4 1067: step4_union(list1, list2, working_line_node, linej_node) 1068: end 1069: else #the working line shares no common line with any line line(k>1) in list1, and working_line < linej 1070: #insert working_line into list1 as the maximal line immediately preceding linej in the list 1071: list1.insert_node(LinearLinkedListNode.new(working_line_node.key.clone, nil, nil)) 1072: #Step 2 1073: step2_union(list1, list2, working_line_node, linej_node) 1074: end 1075: end
Second step of the difference algorithm of Krishnamurti
# File lib/geometry.rb, line 1143 1143: def step2_difference(list1, list2, working_line_node, linej_node) 1144: if (working_line_node._next) 1145: working_line_node = working_line_node._next 1146: step1_difference(list1, list2, working_line_node, linej_node) 1147: else 1148: return 1149: end 1150: end
Second step of the intersection algorithm of Krishnamurti
# File lib/geometry.rb, line 1198 1198: def step2_intersection(list1, list2, list3, working_line_node, linej_node) 1199: if (working_line_node._next) 1200: working_line_node = working_line_node._next 1201: step1_intersection(list1, list2, list3, working_line_node, linej_node) 1202: end 1203: end
Second step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1078 1078: def step2_union(list1, list2, working_line_node, linej_node) 1079: if (working_line_node._next) 1080: working_line_node = working_line_node._next 1081: #GOTO step1 1082: step1_union(list1, list2, working_line_node, linej_node) 1083: else 1084: #Step 9 1085: return 1086: end 1087: end
Fourth step of the difference algorithm of Krishnamurti
# File lib/geometry.rb, line 1153 1153: def step4_difference(list1, list2, working_line_node, linej_node) 1154: if (linej_node._next) 1155: linej_node = linej_node._next 1156: step1_difference(list1, list2, working_line_node, linej_node) 1157: else 1158: return 1159: end 1160: end
Fourth step of the intersection algorithm of Krishnamurti
# File lib/geometry.rb, line 1206 1206: def step4_intersection(list1, list2, list3, working_line_node, linej_node) 1207: if (linej_node._next) 1208: linej_node = linej_node._next 1209: step1_intersection(list1, list2, list3, working_line, linej) 1210: end 1211: end
Fourth step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1090 1090: def step4_union(list1, list2, working_line_node, linej_node) 1091: if (linej_node._next) 1092: linej_node = linej_node._next 1093: #GOTO step1 1094: step1_union(list1, list2, working_line_node, linej_node) 1095: else 1096: list1.insert_node(LinearLinkedListNode.new(working_line_node.key.clone, nil, nil)) 1097: #GOTO Step 8 1098: step8_union(list1, list2, working_line_node, linej_node) 1099: end 1100: end
Eighth step of the union algorithm of Krishnamurti
# File lib/geometry.rb, line 1103 1103: def step8_union(list1, list2, working_line_node, linej_node) 1104: while (working_line_node) 1105: list1.insert_node(LinearLinkedListNode.new(working_line_node.key.clone, nil, nil)) 1106: working_line_node = working_line_node._next 1107: end 1108: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.