extend Python interface of sketcher and make non-parametic version working

This commit is contained in:
wmayer 2016-08-14 11:52:37 +02:00
parent d4bb01835c
commit bfb80b058c
5 changed files with 70 additions and 34 deletions

View File

@ -110,9 +110,8 @@ int Sketch::setUpSketch(const std::vector<Part::Geometry *> &GeoList,
const std::vector<Constraint *> &ConstraintList, const std::vector<Constraint *> &ConstraintList,
int extGeoCount) int extGeoCount)
{ {
Base::TimeInfo start_time; Base::TimeInfo start_time;
clear(); clear();
std::vector<Part::Geometry *> intGeoList, extGeoList; std::vector<Part::Geometry *> intGeoList, extGeoList;
@ -129,7 +128,7 @@ int Sketch::setUpSketch(const std::vector<Part::Geometry *> &GeoList,
Geoms[i].external = true; Geoms[i].external = true;
// The Geoms list might be empty after an undo/redo // The Geoms list might be empty after an undo/redo
if (!Geoms.empty()) { if (!Geoms.empty()) {
addConstraints(ConstraintList); addConstraints(ConstraintList);
} }
GCSsys.clearByTag(-1); GCSsys.clearByTag(-1);
@ -137,13 +136,24 @@ int Sketch::setUpSketch(const std::vector<Part::Geometry *> &GeoList,
GCSsys.initSolution(defaultSolverRedundant); GCSsys.initSolution(defaultSolverRedundant);
GCSsys.getConflicting(Conflicting); GCSsys.getConflicting(Conflicting);
GCSsys.getRedundant(Redundant); GCSsys.getRedundant(Redundant);
if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel) { if (debugMode==GCS::Minimal || debugMode==GCS::IterationLevel) {
Base::TimeInfo end_time; Base::TimeInfo end_time;
Base::Console().Log("Sketcher::setUpSketch()-T:%s\n",Base::TimeInfo::diffTime(start_time,end_time).c_str()); Base::Console().Log("Sketcher::setUpSketch()-T:%s\n",Base::TimeInfo::diffTime(start_time,end_time).c_str());
} }
return GCSsys.dofsNumber();
}
int Sketch::resetSolver()
{
GCSsys.clearByTag(-1);
GCSsys.declareUnknowns(Parameters);
GCSsys.initSolution(defaultSolverRedundant);
GCSsys.getConflicting(Conflicting);
GCSsys.getRedundant(Redundant);
return GCSsys.dofsNumber(); return GCSsys.dofsNumber();
} }
@ -567,9 +577,10 @@ std::vector<Part::Geometry *> Sketch::extractGeometry(bool withConstructionEleme
{ {
std::vector<Part::Geometry *> temp; std::vector<Part::Geometry *> temp;
temp.reserve(Geoms.size()); temp.reserve(Geoms.size());
for (std::vector<GeoDef>::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it) for (std::vector<GeoDef>::const_iterator it=Geoms.begin(); it != Geoms.end(); ++it) {
if ((!it->external || withExternalElements) && (!it->geo->Construction || withConstructionElements)) if ((!it->external || withExternalElements) && (!it->geo->Construction || withConstructionElements))
temp.push_back(it->geo->clone()); temp.push_back(it->geo->clone());
}
return temp; return temp;
} }
@ -2090,18 +2101,17 @@ bool Sketch::updateNonDrivingConstraints()
int Sketch::solve(void) int Sketch::solve(void)
{ {
Base::TimeInfo start_time; Base::TimeInfo start_time;
if (!isInitMove) { // make sure we are in single subsystem mode if (!isInitMove) { // make sure we are in single subsystem mode
GCSsys.clearByTag(-1); GCSsys.clearByTag(-1);
isFine = true; isFine = true;
} }
int ret = -1; int ret = -1;
bool valid_solution; bool valid_solution;
std::string solvername; std::string solvername;
int defaultsoltype = -1; int defaultsoltype = -1;
if(isInitMove){ if(isInitMove){
solvername = "DogLeg"; // DogLeg is used for dragging (same as before) solvername = "DogLeg"; // DogLeg is used for dragging (same as before)
ret = GCSsys.solve(isFine, GCS::DogLeg); ret = GCSsys.solve(isFine, GCS::DogLeg);
@ -2123,9 +2133,9 @@ int Sketch::solve(void)
ret = GCSsys.solve(isFine, GCS::DogLeg); ret = GCSsys.solve(isFine, GCS::DogLeg);
defaultsoltype=0; defaultsoltype=0;
break; break;
} }
} }
// if successfully solved try to write the parameters back // if successfully solved try to write the parameters back
if (ret == GCS::Success) { if (ret == GCS::Success) {
GCSsys.applySolution(); GCSsys.applySolution();
@ -2134,11 +2144,12 @@ int Sketch::solve(void)
GCSsys.undoSolution(); GCSsys.undoSolution();
updateGeometry(); updateGeometry();
Base::Console().Warning("Invalid solution from %s solver.\n", solvername.c_str()); Base::Console().Warning("Invalid solution from %s solver.\n", solvername.c_str());
}else }
{ else {
updateNonDrivingConstraints(); updateNonDrivingConstraints();
} }
} else { }
else {
valid_solution = false; valid_solution = false;
if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel){ if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel){
@ -2148,11 +2159,11 @@ int Sketch::solve(void)
if(!valid_solution && !isInitMove) { // Fall back to other solvers if(!valid_solution && !isInitMove) { // Fall back to other solvers
for (int soltype=0; soltype < 4; soltype++) { for (int soltype=0; soltype < 4; soltype++) {
if(soltype==defaultsoltype){ if(soltype==defaultsoltype){
continue; // skip default solver continue; // skip default solver
} }
switch (soltype) { switch (soltype) {
case 0: case 0:
solvername = "DogLeg"; solvername = "DogLeg";
@ -2197,7 +2208,7 @@ int Sketch::solve(void)
if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel){ if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel){
Base::Console().Log("Sketcher::Solve()-%s- Failed!! Falling back...\n",solvername.c_str()); Base::Console().Log("Sketcher::Solve()-%s- Failed!! Falling back...\n",solvername.c_str());
} }
} }
if (soltype == 3) // cleanup temporary constraints of the augmented system if (soltype == 3) // cleanup temporary constraints of the augmented system
@ -2222,12 +2233,12 @@ int Sketch::solve(void)
} }
Base::TimeInfo end_time; Base::TimeInfo end_time;
if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel){ if(debugMode==GCS::Minimal || debugMode==GCS::IterationLevel){
Base::Console().Log("Sketcher::Solve()-%s-T:%s\n",solvername.c_str(),Base::TimeInfo::diffTime(start_time,end_time).c_str()); Base::Console().Log("Sketcher::Solve()-%s-T:%s\n",solvername.c_str(),Base::TimeInfo::diffTime(start_time,end_time).c_str());
} }
SolveTime = Base::TimeInfo::diffTimeF(start_time,end_time); SolveTime = Base::TimeInfo::diffTimeF(start_time,end_time);
return ret; return ret;
} }
@ -2316,7 +2327,7 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
GCSsys.rescaleConstraint(i, 0.01); GCSsys.rescaleConstraint(i, 0.01);
} }
} else if (Geoms[geoId].type == Ellipse) { } else if (Geoms[geoId].type == Ellipse) {
GCS::Point &center = Points[Geoms[geoId].midPointId]; GCS::Point &center = Points[Geoms[geoId].midPointId];
GCS::Point p0,p1; GCS::Point p0,p1;
if (pos == mid || pos == none) { if (pos == mid || pos == none) {
@ -2328,7 +2339,7 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
GCSsys.addConstraintP2PCoincident(p0,center,-1); GCSsys.addConstraintP2PCoincident(p0,center,-1);
} }
} else if (Geoms[geoId].type == ArcOfEllipse) { } else if (Geoms[geoId].type == ArcOfEllipse) {
GCS::Point &center = Points[Geoms[geoId].midPointId]; GCS::Point &center = Points[Geoms[geoId].midPointId];
GCS::Point p0,p1; GCS::Point p0,p1;
if (pos == mid || pos == none) { if (pos == mid || pos == none) {
@ -2339,7 +2350,7 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
*p0.y = *center.y; *p0.y = *center.y;
GCSsys.addConstraintP2PCoincident(p0,center,-1); GCSsys.addConstraintP2PCoincident(p0,center,-1);
} else if (pos == start || pos == end) { } else if (pos == start || pos == end) {
MoveParameters.resize(4); // x,y,cx,cy MoveParameters.resize(4); // x,y,cx,cy
if (pos == start || pos == end) { if (pos == start || pos == end) {
GCS::Point &p = (pos == start) ? Points[Geoms[geoId].startPointId] GCS::Point &p = (pos == start) ? Points[Geoms[geoId].startPointId]
@ -2349,7 +2360,8 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine)
*p0.x = *p.x; *p0.x = *p.x;
*p0.y = *p.y; *p0.y = *p.y;
GCSsys.addConstraintP2PCoincident(p0,p,-1); GCSsys.addConstraintP2PCoincident(p0,p,-1);
} }
p1.x = &MoveParameters[2]; p1.x = &MoveParameters[2];
p1.y = &MoveParameters[3]; p1.y = &MoveParameters[3];
*p1.x = *center.x; *p1.x = *center.x;
@ -2493,8 +2505,6 @@ Base::Vector3d Sketch::getPoint(int geoId, PointPos pos)
return Base::Vector3d(); return Base::Vector3d();
} }
TopoShape Sketch::toShape(void) const TopoShape Sketch::toShape(void) const
{ {
TopoShape result; TopoShape result;
@ -2563,6 +2573,7 @@ TopoShape Sketch::toShape(void) const
aFix.FixClosed(); aFix.FixClosed();
wires.push_back(aFix.Wire()); wires.push_back(aFix.Wire());
} }
if (wires.size() == 1) if (wires.size() == 1)
result = *wires.begin(); result = *wires.begin();
else if (wires.size() > 1) { else if (wires.size() > 1) {

View File

@ -51,6 +51,8 @@ public:
/// solve the actual set up sketch /// solve the actual set up sketch
int solve(void); int solve(void);
/// resets the solver
int resetSolver();
/// get standard (aka fine) solver precision /// get standard (aka fine) solver precision
double getSolverPrecision(){ return GCSsys.getFinePrecision(); } double getSolverPrecision(){ return GCSsys.getFinePrecision(); }
/// delete all geometry and constraints, leave an empty sketch /// delete all geometry and constraints, leave an empty sketch

View File

@ -56,11 +56,17 @@
</Documentation> </Documentation>
<Parameter Name="Constraint" Type="Int"/> <Parameter Name="Constraint" Type="Int"/>
</Attribute> </Attribute>
<Attribute Name="Constraints" ReadOnly="true"> <Attribute Name="Conflicts" ReadOnly="true">
<Documentation> <Documentation>
<UserDocu>Tuple of all constrains in this sketch</UserDocu> <UserDocu>Tuple of conflicting constraints</UserDocu>
</Documentation> </Documentation>
<Parameter Name="Constraints" Type="Tuple"/> <Parameter Name="Conflicts" Type="Tuple"/>
</Attribute>
<Attribute Name="Redundancies" ReadOnly="true">
<Documentation>
<UserDocu>Tuple of redundant constraints</UserDocu>
</Documentation>
<Parameter Name="Redundancies" Type="Tuple"/>
</Attribute> </Attribute>
<Attribute Name="Geometries" ReadOnly="true"> <Attribute Name="Geometries" ReadOnly="true">
<Documentation> <Documentation>

View File

@ -63,6 +63,7 @@ int SketchPy::PyInit(PyObject* /*args*/, PyObject* /*kwd*/)
PyObject* SketchPy::solve(PyObject *args) PyObject* SketchPy::solve(PyObject *args)
{ {
getSketchPtr()->resetSolver();
return Py::new_reference_to(Py::Int(getSketchPtr()->solve())); return Py::new_reference_to(Py::Int(getSketchPtr()->solve()));
} }
@ -169,10 +170,26 @@ Py::Int SketchPy::getConstraint(void) const
throw Py::AttributeError("Not yet implemented"); throw Py::AttributeError("Not yet implemented");
} }
Py::Tuple SketchPy::getConstraints(void) const Py::Tuple SketchPy::getConflicts(void) const
{ {
//return Py::Tuple(); std::vector<int> c = getSketchPtr()->getConflicting();
throw Py::AttributeError("Not yet implemented"); Py::Tuple t(c.size());
for (std::size_t i=0; i<c.size(); i++) {
t.setItem(i, Py::Long(c[i]));
}
return t;
}
Py::Tuple SketchPy::getRedundancies(void) const
{
std::vector<int> c = getSketchPtr()->getRedundant();
Py::Tuple t(c.size());
for (std::size_t i=0; i<c.size(); i++) {
t.setItem(i, Py::Long(c[i]));
}
return t;
} }
Py::Tuple SketchPy::getGeometries(void) const Py::Tuple SketchPy::getGeometries(void) const

View File

@ -252,7 +252,7 @@ namespace GCS
double getFinePrecision(){ return convergence;} double getFinePrecision(){ return convergence;}
int diagnose(Algorithm alg=DogLeg); int diagnose(Algorithm alg=DogLeg);
int dofsNumber() { return hasDiagnosis ? dofs : -1; } int dofsNumber() const { return hasDiagnosis ? dofs : -1; }
void getConflicting(VEC_I &conflictingOut) const void getConflicting(VEC_I &conflictingOut) const
{ conflictingOut = hasDiagnosis ? conflictingTags : VEC_I(0); } { conflictingOut = hasDiagnosis ? conflictingTags : VEC_I(0); }
void getRedundant(VEC_I &redundantOut) const void getRedundant(VEC_I &redundantOut) const