mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-19 20:44:16 +02:00
A new wire takes the potential of a terminal it reaches through another
ConductorCreator::existingPotential() looked for an existing potential only at the terminals being wired and, for a report, at its partner's first conductor. A wire drawn to the free side of a terminal element whose other side is wired, or to the far side of such a chain, found none and got the folio's default properties: the neutral after a terminal strip came out solid and unnumbered while relatedPotentialConductors() counts it as part of the dashed, numbered N potential. Each terminal is now followed through relatedPotentialTerminal() -- the rule relatedPotentialConductors() applies -- until a wired terminal is found, and two terminals on one potential count once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4555,6 +4555,34 @@ class Integration(unittest.TestCase):
|
||||
rows = m.tool_conductors(r["output"])["conductors"]
|
||||
self.assertEqual([c["num"] for c in rows], ["W7", "W7"])
|
||||
|
||||
def test_new_conductor_inherits_a_potential_through_terminal_and_report(self):
|
||||
"""A wire drawn to the free side of a terminal element, or to a
|
||||
report linked to a wired one, is on that potential already: it
|
||||
takes the potential's number and line style, not the folio's
|
||||
defaults (ConductorCreator::existingPotential)."""
|
||||
base = self.sb.new()
|
||||
ops = [{"op": "add_folio", "id": "f"}, {"op": "add_folio", "id": "g"},
|
||||
{"op": "add_element", "id": "a", "folio": "$f", "path": COIL, "x": 100, "y": 100},
|
||||
{"op": "add_element", "id": "t", "folio": "$f", "path": TERMINAL, "x": 300, "y": 300},
|
||||
{"op": "add_element", "id": "b", "folio": "$f", "path": COIL, "x": 500, "y": 100},
|
||||
{"op": "add_element", "id": "go", "folio": "$f", "path": NEXT_REPORT, "x": 700, "y": 100},
|
||||
{"op": "add_element", "id": "in", "folio": "$g", "path": PREVIOUS_REPORT, "x": 100, "y": 100},
|
||||
{"op": "add_element", "id": "c", "folio": "$g", "path": COIL, "x": 300, "y": 100},
|
||||
{"op": "link_elements", "folio": "$f", "element": "$go", "to_folio": "$g", "to": "$in"},
|
||||
{"op": "add_conductor", "folio": "$f", "from": "$a", "from_terminal": 0, "to": "$t", "to_terminal": 0},
|
||||
{"op": "set_conductor", "folio": "$f", "element": "$a", "terminal": 0, "property": "num", "value": "W7"},
|
||||
{"op": "set_conductor", "folio": "$f", "element": "$a", "terminal": 0, "property": "style", "value": "dashed"},
|
||||
# the terminal's other side, then on through the report
|
||||
{"op": "add_conductor", "folio": "$f", "from": "$t", "from_terminal": 1, "to": "$b", "to_terminal": 0},
|
||||
{"op": "add_conductor", "folio": "$f", "from": "$b", "from_terminal": 0, "to": "$go", "to_terminal": 0},
|
||||
{"op": "add_conductor", "folio": "$g", "from": "$in", "from_terminal": 0, "to": "$c", "to_terminal": 0}]
|
||||
r = self.ok(self.sb.edit(base, ops))
|
||||
rows = m.tool_conductors(r["output"])["conductors"]
|
||||
self.assertEqual([c["num"] for c in rows], ["W7"] * 4)
|
||||
styles = {c["value"] for c in m.tool_conductors(r["output"], attribute="style")["conductors"]}
|
||||
self.assertEqual(len(styles), 1, styles)
|
||||
self.assertIn("dash", styles.pop())
|
||||
|
||||
# ---- conductor manual routing ----
|
||||
|
||||
def test_move_conductor_segment_reroutes_the_path(self):
|
||||
|
||||
@@ -179,46 +179,65 @@ bool ConductorCreator::setUpPropertieToUse()
|
||||
|
||||
/**
|
||||
@brief ConductorCreator::existingPotential
|
||||
Return the list of existing potential of
|
||||
the terminal list
|
||||
Return one conductor of each existing potential the terminals of
|
||||
@p terminals_list are on.
|
||||
|
||||
A terminal without a wire of its own can still be on a potential: the
|
||||
other side of a terminal element, a folio report linked to one that is
|
||||
wired. Such a terminal is followed through relatedPotentialTerminal()
|
||||
until a wired terminal is found -- the rule Conductor::
|
||||
relatedPotentialConductors() applies, so that a wire drawn to the
|
||||
free side of a terminal takes the properties (number, colour, line
|
||||
style...) of the potential the terminal already carries instead of the
|
||||
folio's defaults.
|
||||
Two terminals on the same potential give that potential once.
|
||||
@param terminals_list the terminals to inspect
|
||||
@return c_list QList<Conductor *>
|
||||
*/
|
||||
QList<Conductor *> ConductorCreator::existingPotential(const QList<Terminal *> &terminals_list)
|
||||
{
|
||||
QList<Conductor *> c_list;
|
||||
QList<Terminal *> t_exclude;
|
||||
|
||||
QList<QSet<Conductor *>> potentials;
|
||||
|
||||
for (Terminal *t : terminals_list)
|
||||
{
|
||||
if (t_exclude.contains(t)) {
|
||||
Conductor *seed = nullptr;
|
||||
QList<Terminal *> to_visit {t};
|
||||
QSet<const Terminal *> visited;
|
||||
while (!to_visit.isEmpty() && !seed)
|
||||
{
|
||||
Terminal *current = to_visit.takeFirst();
|
||||
if (visited.contains(current)) {
|
||||
continue;
|
||||
}
|
||||
visited.insert(current);
|
||||
if (!current->conductors().isEmpty()) {
|
||||
seed = current->conductors().first();
|
||||
} else {
|
||||
to_visit += relatedPotentialTerminal(current, true);
|
||||
}
|
||||
}
|
||||
if (!seed) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!t->conductors().isEmpty())
|
||||
{
|
||||
c_list.append(t->conductors().first());
|
||||
|
||||
//We must check if m_terminals_list contains a terminal
|
||||
//in the same potential of c, and if true, exclude this terminal from the search.
|
||||
for (Conductor *c : t->conductors().first()->relatedPotentialConductors(false))
|
||||
{
|
||||
if (terminals_list.contains(c->terminal1)) {
|
||||
t_exclude.append(c->terminal1);
|
||||
} else if (terminals_list.contains(c->terminal2)) {
|
||||
t_exclude.append(c->terminal2);
|
||||
}
|
||||
|
||||
bool known = false;
|
||||
for (const QSet<Conductor *> &potential : std::as_const(potentials)) {
|
||||
if (potential.contains(seed)) {
|
||||
known = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (t->parentElement()->linkType() & Element::AllReport && !t->parentElement()->isFree())
|
||||
{
|
||||
Element *linked_report = t->parentElement()->linkedElements().first();
|
||||
if (!linked_report->conductors().isEmpty()) {
|
||||
c_list.append(linked_report->conductors().first());
|
||||
}
|
||||
if (known) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QSet<Conductor *> potential = seed->relatedPotentialConductors(true);
|
||||
potential.insert(seed);
|
||||
potentials.append(potential);
|
||||
c_list.append(seed);
|
||||
}
|
||||
|
||||
|
||||
return c_list;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user