Sketcher: Bug fixes: inability to create links to external geometry

=================================================================

First bug: Inability to create links to external geometry as described here:
http://forum.freecadweb.org/download/file.php?id=16668

Second bug: FC crashes on changing the support after having imported external geometry as described here:
http://forum.freecadweb.org/viewtopic.php?f=10&t=12380

and solving this ticket:
http://www.freecadweb.org/tracker/view.php?id=2225

Solution to first bug:

If for some reason a sketch ends up having a list of external geometries (property) that can not be recreated (rebuilt),
they remain latent, do not show the external elements in the elements widget or in the screen and prevent adding the
elements again.

In cases where the saved file contains invalid external geometry links (which will give raise to a handled exception that would prevent external geometry creation),
this condition gets detected during restore and the invalid links are deleted before external geometry creation, so as to allow the rest of external links to be recreated.

Solution to second bug:

It is also related to invalid external links (the link was existing, but upon change on the support, it is possible that an external edge is no longer valid, reduction of edges in support).
This situation is detected upon entering into edit mode, and the invalid ones are deleted.

Note that there is still the possibility for the user to remap an invalid sketch BEFORE editing, if the remapping is successful, it may not be necessary to delete links (all depends on the
specific case).
This commit is contained in:
Abdullah Tahiri 2015-09-08 20:08:47 +02:00 committed by wmayer
parent 185735ca2c
commit 47c0859c1b
3 changed files with 104 additions and 1 deletions

View File

@ -2763,6 +2763,98 @@ const Part::Geometry* SketchObject::getGeometry(int GeoId) const
return 0;
}
bool SketchObject::evaluateSupport(void)
{
// returns false if the shape if broken, null or non-planar
Part::Feature *part = static_cast<Part::Feature*>(Support.getValue());
if (!part || !part->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
return false;
const std::vector<std::string> &sub = Support.getSubValues();
assert(sub.size()==1);
// get the selected sub shape (a Face)
const Part::TopoShape &shape = part->Shape.getShape();
if (shape._Shape.IsNull())
return false;
TopoDS_Shape sh;
try {
sh = shape.getSubShape(sub[0].c_str());
}
catch (Standard_Failure) {
return false;
}
const TopoDS_Face &face = TopoDS::Face(sh);
if (face.IsNull())
return false;
BRepAdaptor_Surface adapt(face);
if (adapt.GetType() != GeomAbs_Plane)
return false; // No planar face
return true;
}
void SketchObject::validateExternalLinks(void)
{
std::vector<DocumentObject*> Objects = ExternalGeometry.getValues();
std::vector<std::string> SubElements = ExternalGeometry.getSubValues();
bool rebuild = false ;
for (int i=0; i < int(Objects.size()); i++) {
const App::DocumentObject *Obj=Objects[i];
const std::string SubElement=SubElements[i];
const Part::Feature *refObj=static_cast<const Part::Feature*>(Obj);
const Part::TopoShape& refShape=refObj->Shape.getShape();
TopoDS_Shape refSubShape;
try {
refSubShape = refShape.getSubShape(SubElement.c_str());
}
catch (Standard_Failure) {
rebuild = true ;
Objects.erase(Objects.begin()+i);
SubElements.erase(SubElements.begin()+i);
const std::vector< Constraint * > &constraints = Constraints.getValues();
std::vector< Constraint * > newConstraints(0);
int GeoId = -3 - i;
for (std::vector<Constraint *>::const_iterator it = constraints.begin();
it != constraints.end(); ++it) {
if ((*it)->First != GeoId && (*it)->Second != GeoId && (*it)->Third != GeoId) {
Constraint *copiedConstr = (*it)->clone();
if (copiedConstr->First < GeoId &&
copiedConstr->First != Constraint::GeoUndef)
copiedConstr->First += 1;
if (copiedConstr->Second < GeoId &&
copiedConstr->Second != Constraint::GeoUndef)
copiedConstr->Second += 1;
if (copiedConstr->Third < GeoId &&
copiedConstr->Third != Constraint::GeoUndef)
copiedConstr->Third += 1;
newConstraints.push_back(copiedConstr);
}
}
Constraints.setValues(newConstraints);
i--; // we deleted an item, so the next one took its place
}
}
if (rebuild) {
ExternalGeometry.setValues(Objects,SubElements);
rebuildExternalGeometry();
Constraints.acceptGeometry(getCompleteGeometry());
rebuildVertexIndex();
solve(true); // we have to update this sketch and everything depending on it.
}
}
void SketchObject::rebuildExternalGeometry(void)
{
// get the actual lists of the externals
@ -3570,7 +3662,10 @@ void SketchObject::onChanged(const App::Property* prop)
void SketchObject::onDocumentRestored()
{
try {
rebuildExternalGeometry();
if(Support.getValue()) {
validateExternalLinks();
rebuildExternalGeometry();
}
Constraints.acceptGeometry(getCompleteGeometry());
}
catch (...) {

View File

@ -222,6 +222,10 @@ public:
bool evaluateConstraints() const;
/// Remove constraints with invalid indexes
void validateConstraints();
/// Checks if support is valid
bool evaluateSupport(void);
/// validate External Links (remove invalid external links)
void validateExternalLinks(void);
/// gets DoF of last solver execution
inline int getLastDoF() const {return lastDoF;}

View File

@ -4223,6 +4223,10 @@ bool ViewProviderSketch::setEdit(int ModNum)
// The false parameter indicates that the geometry of the SketchObject shall not be updateData
// so as not to trigger an onChanged that would set the document as modified and trigger a recompute
// if we just close the sketch without touching anything.
if(getSketchObject()->Support.getValue())
if (!getSketchObject()->evaluateSupport())
getSketchObject()->validateExternalLinks();
getSketchObject()->solve(false);
UpdateSolverInformation();
draw(false);