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:
parent
185735ca2c
commit
47c0859c1b
|
@ -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 (...) {
|
||||
|
|
|
@ -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;}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user