Skip to content

Commit

Permalink
App: change Property::getPaths() and getPyPathValue()
Browse files Browse the repository at this point in the history
Since ExpressionCompleter will now look into Python attributes, there
is no need to expose duplicated information through getPaths(), except
those that provides extra information (e.g. Rotation.Angle with extra
unit information)

getPyPathValue() is modified to return Python attributes after the
given path.
  • Loading branch information
realthunder committed Jun 16, 2020
1 parent 85b037d commit 3b5388d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 47 deletions.
3 changes: 2 additions & 1 deletion src/App/Property.cpp
Expand Up @@ -130,7 +130,8 @@ const boost::any Property::getPathValue(const ObjectIdentifier &path) const

void Property::getPaths(std::vector<ObjectIdentifier> &paths) const
{
paths.emplace_back(getContainer(), getName());
(void)paths;
// paths.emplace_back(getContainer(), getName());
}

ObjectIdentifier Property::canonicalPath(const ObjectIdentifier &p) const
Expand Down
90 changes: 58 additions & 32 deletions src/App/PropertyGeo.cpp
Expand Up @@ -223,15 +223,23 @@ bool PropertyVector::getPyPathValue(const ObjectIdentifier &path, Py::Object &re
if(unit.isEmpty())
return false;

std::string p = path.getSubPathStr();
if (p == ".x") {
res = new QuantityPy(new Quantity(getValue().x,unit));
} else if(p == ".y") {
res = new QuantityPy(new Quantity(getValue().y,unit));
} else if(p == ".z") {
res = new QuantityPy(new Quantity(getValue().z,unit));
} else
return false;
int i=0;
for(auto &c : path.getPropertyComponents(1)) {
if(i == 0) {
if(!c.isSimple())
return false;
if(c.getName() == "x") {
res = Py::asObject(new QuantityPy(new Quantity(getValue().x,unit)));
} else if(c.getName() == "y") {
res = Py::asObject(new QuantityPy(new Quantity(getValue().y,unit)));
} else if(c.getName() == "z") {
res = Py::asObject(new QuantityPy(new Quantity(getValue().z,unit)));
} else
return false;
continue;
}
res = c.get(res);
}
return true;
}

Expand Down Expand Up @@ -612,18 +620,24 @@ void PropertyPlacement::getPaths(std::vector<ObjectIdentifier> &paths) const
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Angle")));
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
paths.push_back(ObjectIdentifier(*this)
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
<< ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));

// Unlike the above path (which provides units that are not available
// through python, the following paths provides the same value. They are no
// longer needed, because the expression completer will now dig into all
// python attributes.

// paths.push_back(ObjectIdentifier(*this)
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("x")));
// paths.push_back(ObjectIdentifier(*this)
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("y")));
// paths.push_back(ObjectIdentifier(*this)
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Rotation"))
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("Axis"))
// << ObjectIdentifier::SimpleComponent(ObjectIdentifier::String("z")));
}

void PropertyPlacement::setPathValue(const ObjectIdentifier &path, const boost::any &value)
Expand Down Expand Up @@ -674,19 +688,31 @@ const boost::any PropertyPlacement::getPathValue(const ObjectIdentifier &path) c

bool PropertyPlacement::getPyPathValue(const ObjectIdentifier &path, Py::Object &res) const
{
std::string p = path.getSubPathStr();
if (p == ".Rotation.Angle") {
auto components = path.getPropertyComponents(1);
if(components.size() < 2)
return false;
if(components[0].isSimple() && components[0].getName() == "Rotation") {
if(components[1].isSimple() && components[1].getName() != "Angle")
return false;
Base::Vector3d axis; double angle;
_cPos.getRotation().getValue(axis,angle);
res = new QuantityPy(new Quantity(Base::toDegrees(angle),Unit::Angle));
} else if (p == ".Base.x") {
res = new QuantityPy(new Quantity(_cPos.getPosition().x,Unit::Length));
} else if (p == ".Base.y") {
res = new QuantityPy(new Quantity(_cPos.getPosition().y,Unit::Length));
} else if (p == ".Base.z") {
res = new QuantityPy(new Quantity(_cPos.getPosition().z,Unit::Length));
} else
return false;
res = Py::asObject(new QuantityPy(new Quantity(Base::toDegrees(angle),Unit::Angle)));
}
else if(components[0].isSimple() && components[0].getName() == "Base") {
if(!components[1].isSimple())
return false;
if(components[1].getName() == "x") {
res = Py::asObject(new QuantityPy(new Quantity(_cPos.getPosition().x,Unit::Length)));
} else if(components[1].getName() == "y") {
res = Py::asObject(new QuantityPy(new Quantity(_cPos.getPosition().y,Unit::Length)));
} else if(components[1].getName() == "z") {
res = Py::asObject(new QuantityPy(new Quantity(_cPos.getPosition().z,Unit::Length)));
} else
return false;
}

for(size_t i=2;i<components.size();++i)
res = components[i].get(res);
return true;
}

Expand Down
24 changes: 14 additions & 10 deletions src/Mod/Part/App/PropertyTopoShape.cpp
Expand Up @@ -229,16 +229,20 @@ unsigned int PropertyPartShape::getMemSize (void) const

void PropertyPartShape::getPaths(std::vector<App::ObjectIdentifier> &paths) const
{
paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
<< App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("ShapeType")));
paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
<< App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Orientation")));
paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
<< App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Length")));
paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
<< App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Area")));
paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
<< App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Volume")));
// The paths below seem to only there for expression completer. They are no
// longer required because the completer will now dig into all Python attributes.
(void)paths;

// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("ShapeType")));
// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Orientation")));
// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Length")));
// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Area")));
// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName())
// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Volume")));
}

void PropertyPartShape::Save (Base::Writer &writer) const
Expand Down
11 changes: 7 additions & 4 deletions src/Mod/Sketcher/App/PropertyConstraintList.cpp
Expand Up @@ -251,11 +251,12 @@ PyObject *PropertyConstraintList::getPyObject(void)
}

bool PropertyConstraintList::getPyPathValue(const App::ObjectIdentifier &path, Py::Object &res) const {
if(path.numSubComponents()!=2 || path.getPropertyComponent(0).getName()!=getName())
return false;

const ObjectIdentifier::Component & c1 = path.getPropertyComponent(1);
auto components = path.getPropertyComponents(1);
if(components.size() < 1)
return false;

const ObjectIdentifier::Component & c1 = components[0];
const Constraint *cstr = 0;

if (c1.isArray())
Expand All @@ -272,7 +273,9 @@ bool PropertyConstraintList::getPyPathValue(const App::ObjectIdentifier &path, P
if(!cstr)
return false;
Quantity q = cstr->getPresentationValue();
res = new Base::QuantityPy(new Base::Quantity(q));
res = Py::asObject(new Base::QuantityPy(new Base::Quantity(q)));
for(size_t i=1; i< components.size(); ++i)
res = components[i].get(res);
return true;
}

Expand Down

0 comments on commit 3b5388d

Please sign in to comment.