int node_store_add_part (NodeStore *self, Part *part) { GSList *wire_list, *list; Node *node; SheetPos lookup_key; SheetPos part_pos; gdouble x, y; int i, num_pins; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (IS_NODE_STORE (self), FALSE); g_return_val_if_fail (part != NULL, FALSE); g_return_val_if_fail (IS_PART (part), FALSE); num_pins = part_get_num_pins (part); item_data_get_pos (ITEM_DATA (part), &part_pos); for (i = 0; i < num_pins; i++) { Pin *pins; pins = part_get_pins (part); x = part_pos.x + pins[i].offset.x; y = part_pos.y + pins[i].offset.y; //Use the position of the pin as hash key. lookup_key.x = x; lookup_key.y = y; // Retrieve a node for this position. node = node_store_get_or_create_node (self, lookup_key); // Add all the wires that intersect this pin to the node store. wire_list = wires_at_pos (self, lookup_key); for (list = wire_list; list; list = list->next) { Wire *wire = list->data; NG_DEBUG ("Add pin to wire.\n"); node_add_wire (node, wire); wire_add_node (wire, node); } g_slist_free (wire_list); node_add_pin (node, &pins[i]); } g_object_set (G_OBJECT (part), "store", self, NULL); self->parts = g_list_prepend (self->parts, part); self->items = g_list_prepend (self->items, part); return TRUE; }
/** * register a part to the nodestore */ gboolean node_store_add_part (NodeStore *self, Part *part) { NG_DEBUG ("-0-"); g_return_val_if_fail (self, FALSE); g_return_val_if_fail (IS_NODE_STORE (self), FALSE); g_return_val_if_fail (part, FALSE); g_return_val_if_fail (IS_PART (part), FALSE); GSList *iter, *copy; Node *node; Coords pin_pos; Coords part_pos; int i, num_pins; Pin *pins; num_pins = part_get_num_pins (part); pins = part_get_pins (part); item_data_get_pos (ITEM_DATA (part), &part_pos); for (i = 0; i < num_pins; i++) { // Use the position of the pin as hash key. pin_pos.x = part_pos.x + pins[i].offset.x; pin_pos.y = part_pos.y + pins[i].offset.y; // Retrieve a node for this position. node = node_store_get_or_create_node (self, pin_pos); // Add all the wires that intersect this pin to the node store. copy = get_wires_at_pos (self, pin_pos); for (iter = copy; iter; iter = iter->next) { Wire *wire = copy->data; node_add_wire (node, wire); wire_add_node (wire, node); } g_slist_free (copy); node_add_pin (node, &pins[i]); } g_object_set (G_OBJECT (part), "store", self, NULL); self->parts = g_list_prepend (self->parts, part); self->items = g_list_prepend (self->items, part); return TRUE; }
/** * add/register the wire to the nodestore * * @param store * @param wire * @returns TRUE if the wire was added or merged, else FALSE */ gboolean node_store_add_wire (NodeStore *store, Wire *wire) { GList *list; Node *node; int i = 0; g_return_val_if_fail (store, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); // Check for intersection with other wires. for (list = store->wires; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_WIRE (list->data)); Coords where = {-77.77, -77.77}; Wire *other = list->data; if (do_wires_intersect (wire, other, &where)) { if (is_t_crossing (wire, other, &where) || is_t_crossing (other, wire, &where)) { node = node_store_get_or_create_node (store, where); node_add_wire (node, wire); node_add_wire (node, other); wire_add_node (wire, node); wire_add_node (other, node); NG_DEBUG ("Add wire %p to wire %p @ %lf,%lf.\n", wire, other, where.x, where.y); } else { // magic node removal if a x crossing is overlapped with another wire node = node_store_get_node (store, where); NG_DEBUG ("Nuke that node [ %p ] at coords inbetween", node); if (node) { Coords c[4]; wire_get_start_and_end_pos (other, c + 0, c + 1); wire_get_start_and_end_pos (wire, c + 2, c + 3); if (!coords_equal (&where, c + 0) && !coords_equal (&where, c + 1) && !coords_equal (&where, c + 2) && !coords_equal (&where, c + 3)) { wire_remove_node (wire, node); wire_remove_node (other, node); node_remove_wire (node, wire); node_remove_wire (node, other); } } } } } // Check for overlapping with other wires. do { for (list = store->wires; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_WIRE (list->data)); Wire *other = list->data; Coords so, eo; const gboolean overlap = do_wires_overlap (wire, other, &so, &eo); NG_DEBUG ("overlap [ %p] and [ %p ] -- %s", wire, other, overlap == TRUE ? "YES" : "NO"); if (overlap) { Node *sn = node_store_get_node (store, eo); Node *en = node_store_get_node (store, so); #if 1 wire = vulcanize_wire (store, wire, other, &so, &eo); node_store_remove_wire (store, g_object_ref (other)); // equiv // wire_unregister // XXX FIXME this // modifies the list // we iterate over! // delay this until idle, so all handlers like adding view // representation are completed so existing wire-items can be deleted // properly // this is not fancy nor nice but seems to work fairly nicly g_idle_add (delayed_wire_delete, other); break; NG_DEBUG ("overlapping of %p with %p ", wire, other); #else if (!sn && !en) { wire = vulcanize_wire (store, wire, other, &so, &eo); } else if (!sn) { NG_DEBUG ("do_something(TM) : %p sn==NULL ", other); } else if (!en) { NG_DEBUG ("do_something(TM) : %p en==NULL ", other); } else { NG_DEBUG ("do_something(TM) : %p else ", other); } #endif } else { NG_DEBUG ("not of %p with %p ", wire, other); } } } while (list); // Check for intersection with parts (pins). for (list = store->parts; list; list = list->next) { g_assert (list->data != NULL); g_assert (IS_PART (list->data)); Coords part_pos; gint num_pins = -1; Part *part = list->data; num_pins = part_get_num_pins (part); item_data_get_pos (ITEM_DATA (part), &part_pos); // Go through all the parts and see which of their // pins that intersect the wire. for (i = 0; i < num_pins; i++) { Pin *pins; Coords lookup_pos; pins = part_get_pins (part); lookup_pos.x = part_pos.x + pins[i].offset.x; lookup_pos.y = part_pos.y + pins[i].offset.y; // If there is a wire at this pin's position, // add it to the return list. if (is_point_on_wire (wire, &lookup_pos)) { Node *node; node = node_store_get_node (store, lookup_pos); if (node != NULL) { // Add the wire to the node (pin) that it intersected. node_add_wire (node, wire); wire_add_node (wire, node); NG_DEBUG ("Add wire %p to pin (node) %p.\n", wire, node); } else { g_warning ("Bug: Found no node at pin at (%g %g).\n", lookup_pos.x, lookup_pos.y); } } } } g_object_set (G_OBJECT (wire), "store", store, NULL); store->wires = g_list_prepend (store->wires, wire); store->items = g_list_prepend (store->items, wire); return TRUE; }
int node_store_add_wire (NodeStore *store, Wire *wire) { gdouble x1, y1, x2, y2; GSList *ip_list, *list; IntersectionPoint *ipoint; Node *node; SheetPos pos, length; g_return_val_if_fail (store != NULL, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); wire_get_pos_and_length (wire, &pos, &length); x1 = pos.x; y1 = pos.y; x2 = x1 + length.x; y2 = y1 + length.y; // Check for intersection with other wires. ip_list = wires_intersect (store, x1, y1, x2, y2); for (list = ip_list; list; list = list->next) { ipoint = list->data; if (IS_EQ (x1, x2) && ((ipoint->pos.y == y1) || (ipoint->pos.y == y2))) { SheetPos w_pos, w_length; gboolean can_join; GSList *nodes; wire_get_pos_and_length (ipoint->wire, &w_pos, &w_length); gdouble _x1, _x2, _y1, _y2; _x1 = w_pos.x; _y1 = w_pos.y; _x2 = _x1 + w_length.x; _y2 = _y1 + w_length.y; can_join = TRUE; nodes = wire_get_nodes (wire); for (; nodes; nodes = nodes->next) { SheetPos p1; Node *node = (Node *)nodes->data; p1.x = _x1; p1.y = _y1; if ((fabs (node->key.x - p1.x) < 1e-3) && (fabs (node->key.y - p1.y) < 1e-3)){ can_join = FALSE; break; } p1.x = _x2; p1.y = _y2; if ((fabs (node->key.x - p1.x) < 1e-3) && (fabs (node->key.y - p1.y) < 1e-3)){ can_join = FALSE; break; } } if (IS_EQ(_x1, _x2) && can_join) { if (w_pos.x < pos.x) pos.x = w_pos.x; if (w_pos.y < pos.y) pos.y = w_pos.y; length.x += w_length.x; length.y += w_length.y; // Update the new size and pos of the wire item_data_unregister (ITEM_DATA (ipoint->wire)); wire_set_length (ipoint->wire, &length); item_data_set_pos (ITEM_DATA (ipoint->wire), &pos); wire_update_bbox (ipoint->wire); item_data_register (ITEM_DATA (ipoint->wire)); // Done!, return -1 so wire is deleted return -1; } } else if (IS_EQ (y1, y2) && ((ipoint->pos.x == x1) || (ipoint->pos.x == x2))) { SheetPos w_pos, w_length; gboolean can_join; GSList *nodes; wire_get_pos_and_length (ipoint->wire, &w_pos, &w_length); gdouble _x1, _x2, _y1, _y2; _x1 = w_pos.x; _y1 = w_pos.y; _x2 = _x1 + w_length.x; _y2 = _y1 + w_length.y; can_join = TRUE; nodes = wire_get_nodes (wire); for (; nodes; nodes = nodes->next) { SheetPos p; Node *node = (Node *)nodes->data; p.x = _x1; p.y = _y1; if ((fabs (node->key.x - p.x) < 1e-3) && (fabs (node->key.y - p.y) < 1e-3)){ can_join = FALSE; break; } p.x = _x2; p.y = _y2; if ((fabs (node->key.x - p.x) < 1e-3) && (fabs (node->key.y - p.y) < 1e-3)){ can_join = FALSE; break; } } if (IS_EQ(_y1, _y2) && can_join) { if (w_pos.x < pos.x) pos.x = w_pos.x; if (w_pos.y < pos.y) pos.y = w_pos.y; length.x += w_length.x; length.y += w_length.y; // Update the new size and pos of the wire item_data_unregister (ITEM_DATA (ipoint->wire)); wire_set_length (ipoint->wire, &length); item_data_set_pos (ITEM_DATA (ipoint->wire), &pos); wire_update_bbox (ipoint->wire); item_data_register (ITEM_DATA (ipoint->wire)); // Done!, return -1 so wire si deleted return -1; } } node = node_store_get_or_create_node (store, ipoint->pos); // Add the wire, and also the wire that is intersected. node_add_wire (node, wire); node_add_wire (node, ipoint->wire); wire_add_node (wire, node); wire_add_node (ipoint->wire, node); NG_DEBUG ("Add wire to wire.\n"); g_free (ipoint); } g_slist_free (ip_list); // Check for intersection with parts (pins). ip_list = wire_intersect_parts (store, wire); for (list = ip_list; list; list = list->next) { node = list->data; // Add the wire to the node (pin) that it intersected. node_add_wire (node, wire); wire_add_node (wire, node); NG_DEBUG ("Add wire to pin.\n"); } g_slist_free (ip_list); g_object_set (G_OBJECT (wire), "store", store, NULL); store->wires = g_list_prepend (store->wires, wire); store->items = g_list_prepend (store->items, wire); return TRUE; }