| 1513 | } |
| 1514 | |
| 1515 | DocumentObject* DocumentObject::resolve(const char* subname, |
| 1516 | App::DocumentObject** parent, |
| 1517 | std::string* childName, |
| 1518 | const char** subElement, |
| 1519 | PyObject** pyObj, |
| 1520 | Base::Matrix4D* pmat, |
| 1521 | bool transform, |
| 1522 | int depth) const |
| 1523 | { |
| 1524 | auto self = const_cast<DocumentObject*>(this); |
| 1525 | if (parent) { |
| 1526 | *parent = nullptr; |
| 1527 | } |
| 1528 | if (subElement) { |
| 1529 | *subElement = nullptr; |
| 1530 | } |
| 1531 | |
| 1532 | auto obj = getSubObject(subname, pyObj, pmat, transform, depth); |
| 1533 | if (!obj || !subname || *subname == 0) { |
| 1534 | return self; |
| 1535 | } |
| 1536 | |
| 1537 | if (!parent && !subElement) { |
| 1538 | return obj; |
| 1539 | } |
| 1540 | |
| 1541 | // NOTE, the convention of '.' separated SubName demands a mandatory ending |
| 1542 | // '.' for each object name in SubName, even if there is no subelement |
| 1543 | // following it. So finding the last dot will give us the end of the last |
| 1544 | // object name. |
| 1545 | const char* dot = nullptr; |
| 1546 | if (Data::isMappedElement(subname) || !(dot = strrchr(subname, '.')) || dot == subname) { |
| 1547 | if (subElement) { |
| 1548 | *subElement = dot ? dot + 1 : subname; |
| 1549 | } |
| 1550 | return obj; // this means no parent object reference in SubName |
| 1551 | } |
| 1552 | |
| 1553 | if (parent) { |
| 1554 | *parent = self; |
| 1555 | } |
| 1556 | |
| 1557 | bool elementMapChecked = false; |
| 1558 | const char* lastDot = dot; |
| 1559 | for (--dot;; --dot) { |
| 1560 | // check for the second last dot, which is the end of the last parent object |
| 1561 | if (*dot == '.' || dot == subname) { |
| 1562 | // We can't get parent object by its name, because the object may be |
| 1563 | // externally linked (i.e. in a different document). So go through |
| 1564 | // getSubObject again. |
| 1565 | if (!elementMapChecked) { |
| 1566 | elementMapChecked = true; |
| 1567 | const char* sub = dot == subname ? dot : dot + 1; |
| 1568 | if (Data::isMappedElement(sub)) { |
| 1569 | lastDot = dot; |
| 1570 | if (dot == subname) { |
| 1571 | break; |
| 1572 | } |