Toponaming: Tests, cleanup, and fix axis drawing
This commit is contained in:
@@ -4783,12 +4783,10 @@ TopoShape& TopoShape::makeElementRefine(const TopoShape& shape, const char* op,
|
||||
return {};
|
||||
|
||||
std::vector<Data::IndexedName> res;
|
||||
int type = shape.shapeType();
|
||||
for(;;) {
|
||||
if(--type < 0)
|
||||
break;
|
||||
const char *shapetype = shapeName((TopAbs_ShapeEnum)type).c_str();
|
||||
for(int idx : findAncestors(shape.getShape(), (TopAbs_ShapeEnum)type))
|
||||
|
||||
for (int type = shape.shapeType() - 1; type >= 0; type--) {
|
||||
const char* shapetype = shapeName((TopAbs_ShapeEnum)type).c_str();
|
||||
for (int idx : findAncestors(shape.getShape(), (TopAbs_ShapeEnum)type))
|
||||
res.emplace_back(shapetype, idx);
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -161,16 +161,6 @@ SketchObject::SketchObject()
|
||||
"Sketch",
|
||||
(App::PropertyType)(App::Prop_None),
|
||||
"Tolerance for fitting arcs of projected external geometry");
|
||||
// ADD_PROPERTY_TYPE(ExternalBSplineMaxDegree,
|
||||
// (0),
|
||||
// "Sketch",
|
||||
// (App::Prop_None),
|
||||
// "Maximum degree of imported external BSpline. Zero to disable simplification");
|
||||
// ADD_PROPERTY_TYPE(ExternalBSplineTolerance,
|
||||
// (0.0),
|
||||
// "Sketch",
|
||||
// (App::Prop_None),
|
||||
// "Tolerance for simplifying imported external BSpline");
|
||||
geoLastId = 0;
|
||||
|
||||
ADD_PROPERTY(InternalShape,
|
||||
@@ -186,22 +176,6 @@ SketchObject::SketchObject()
|
||||
allowOtherBody = true;
|
||||
allowUnaligned = true;
|
||||
|
||||
// for (std::vector<Part::Geometry*>::iterator it = ExternalGeo.begin(); it != ExternalGeo.end();
|
||||
// ++it)
|
||||
// if (*it)
|
||||
// delete *it;
|
||||
// ExternalGeo.clear();
|
||||
// auto HLine = GeometryTypedFacade<Part::GeomLineSegment>::getTypedFacade();
|
||||
// auto VLine = GeometryTypedFacade<Part::GeomLineSegment>::getTypedFacade();
|
||||
// HLine->getTypedGeometry()->setPoints(Base::Vector3d(0, 0, 0), Base::Vector3d(1, 0, 0));
|
||||
// VLine->getTypedGeometry()->setPoints(Base::Vector3d(0, 0, 0), Base::Vector3d(0, 1, 0));
|
||||
// HLine->setConstruction(true);
|
||||
// VLine->setConstruction(true);
|
||||
// ExternalGeo.push_back(HLine->getGeometry());
|
||||
// ExternalGeo.push_back(VLine->getGeometry());
|
||||
// HLine->setOwner(false);// we have transferred the ownership to ExternalGeo
|
||||
// VLine->setOwner(false);// we have transferred the ownership to ExternalGeo
|
||||
|
||||
initExternalGeo();
|
||||
|
||||
rebuildVertexIndex();
|
||||
@@ -236,14 +210,7 @@ SketchObject::SketchObject()
|
||||
registerElementCache(internalPrefix(), &InternalShape);
|
||||
}
|
||||
|
||||
SketchObject::~SketchObject()
|
||||
{
|
||||
// for (std::vector<Part::Geometry*>::iterator it = ExternalGeo.begin(); it != ExternalGeo.end();
|
||||
// ++it)
|
||||
// if (*it)
|
||||
// delete *it;
|
||||
// ExternalGeo.clear();
|
||||
|
||||
SketchObject::~SketchObject() {
|
||||
delete analyser;
|
||||
}
|
||||
|
||||
@@ -252,8 +219,6 @@ void SketchObject::setupObject()
|
||||
ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
ArcFitTolerance.setValue(hGrpp->GetFloat("ArcFitTolerance", Precision::Confusion()*10.0));
|
||||
// ExternalBSplineMaxDegree.setValue(hGrpp->GetInt("ExternalBSplineMaxDegree", 5));
|
||||
// ExternalBSplineTolerance.setValue(hGrpp->GetFloat("ExternalBSplineTolerance", 1e-4));
|
||||
MakeInternals.setValue(hGrpp->GetBool("MakeInternals", false));
|
||||
inherited::setupObject();
|
||||
}
|
||||
@@ -346,8 +311,7 @@ App::DocumentObjectExecReturn* SketchObject::execute()
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
static bool inline checkSmallEdge(const Part::TopoShape &s)
|
||||
{
|
||||
static bool inline checkSmallEdge(const Part::TopoShape &s) {
|
||||
if (s.shapeType() != TopAbs_EDGE)
|
||||
return false;
|
||||
BRepAdaptor_Curve adapt(TopoDS::Edge(s.getShape()));
|
||||
@@ -401,7 +365,6 @@ void SketchObject::buildShape() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// FIXME: Commented since ExternalGeometryFacade is not added
|
||||
for(size_t i=2;i<ExternalGeo.getSize();++i) {
|
||||
auto geo = ExternalGeo[i];
|
||||
auto egf = ExternalGeometryFacade::getFacade(geo);
|
||||
@@ -632,11 +595,6 @@ int SketchObject::solve(bool updateGeoAfterSolving /*=true*/)
|
||||
if (err == 0 && updateGeoAfterSolving) {
|
||||
// set the newly solved geometry
|
||||
std::vector<Part::Geometry*> geomlist = solvedSketch.extractGeometry();
|
||||
// Geometry.setValues(geomlist);
|
||||
// for (std::vector<Part::Geometry*>::iterator it = geomlist.begin(); it != geomlist.end();
|
||||
// ++it)
|
||||
// if (*it)
|
||||
// delete *it;
|
||||
Part::PropertyGeometryList tmp;
|
||||
tmp.setValues(std::move(geomlist));
|
||||
// Only set values if there is actual changes
|
||||
@@ -1349,6 +1307,10 @@ int SketchObject::toggleVirtualSpace(int ConstrId)
|
||||
|
||||
this->Constraints.setValues(std::move(newVals));
|
||||
|
||||
// Solver didn't actually update, but we need this to inform view provider
|
||||
// to redraw
|
||||
signalSolverUpdate();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1925,26 +1887,109 @@ int SketchObject::setConstruction(int GeoId, bool on)
|
||||
// no need to check input data validity as this is an sketchobject managed operation.
|
||||
Base::StateLocker lock(managedoperation, true);
|
||||
|
||||
#ifdef FC_USE_TNP_FIX
|
||||
Part::PropertyGeometryList *prop;
|
||||
int idx;
|
||||
if (GeoId >= 0) {
|
||||
prop = &Geometry;
|
||||
if (GeoId < Geometry.getSize())
|
||||
idx = GeoId;
|
||||
else
|
||||
return -1;
|
||||
}else if (GeoId <= GeoEnum::RefExt && -GeoId-1 < ExternalGeo.getSize()) {
|
||||
prop = &ExternalGeo;
|
||||
idx = -GeoId-1;
|
||||
}else
|
||||
return -1;
|
||||
#else
|
||||
const std::vector<Part::Geometry*>& vals = getInternalGeometry();
|
||||
if (GeoId < 0 || GeoId >= int(vals.size()))
|
||||
return -1;
|
||||
|
||||
if (getGeometryFacade(GeoId)->isInternalAligned())
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
// While it may seem that there is not a need to trigger an update at this time, because the
|
||||
// solver has its own copy of the geometry, and updateColors of the viewprovider may be
|
||||
// triggered by the clearselection of the UI command, this won't update the elements widget, in
|
||||
// the accumulative of actions it is judged that it is worth to trigger an update here.
|
||||
|
||||
#ifdef FC_USE_TNP_FIX
|
||||
std::unique_ptr<Part::Geometry> geo(prop->getValues()[idx]->clone());
|
||||
if(prop == &Geometry)
|
||||
GeometryFacade::setConstruction(geo.get(), on);
|
||||
else {
|
||||
auto egf = ExternalGeometryFacade::getFacade(geo.get());
|
||||
egf->setFlag(ExternalGeometryExtension::Defining, on);
|
||||
}
|
||||
|
||||
prop->set1Value(idx,std::move(geo));
|
||||
|
||||
#else
|
||||
std::unique_ptr<Part::Geometry> geo(vals[GeoId]->clone());
|
||||
GeometryFacade::setConstruction(geo.get(), on);
|
||||
this->Geometry.set1Value(GeoId, std::move(geo));
|
||||
|
||||
#endif
|
||||
solverNeedsUpdate = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SketchObject::toggleExternalGeometryFlag(const std::vector<int> &geoIds,
|
||||
const std::vector<ExternalGeometryExtension::Flag> &flags)
|
||||
{
|
||||
if (flags.empty())
|
||||
return 0;
|
||||
auto flag = flags.front();
|
||||
|
||||
Base::StateLocker lock(managedoperation, true); // no need to check input data validity as this is an sketchobject managed operation.
|
||||
|
||||
bool update = false;
|
||||
bool touched = false;
|
||||
auto geos = ExternalGeo.getValues();
|
||||
std::set<int> idSet(geoIds.begin(),geoIds.end());
|
||||
for(auto geoId : geoIds) {
|
||||
if(geoId > GeoEnum::RefExt || -geoId-1>=ExternalGeo.getSize())
|
||||
continue;
|
||||
if(!idSet.count(geoId))
|
||||
continue;
|
||||
idSet.erase(geoId);
|
||||
int idx = -geoId-1;
|
||||
auto &geo = geos[idx];
|
||||
auto egf = ExternalGeometryFacade::getFacade(geo);
|
||||
bool value = !egf->testFlag(flag);
|
||||
if(egf->getRef().size()) {
|
||||
for(auto gid : getRelatedGeometry(geoId)) {
|
||||
if(gid == geoId)
|
||||
continue;
|
||||
int idx = -gid-1;
|
||||
auto &g = geos[idx];
|
||||
g = g->clone();
|
||||
auto egf = ExternalGeometryFacade::getFacade(g);
|
||||
egf->setFlag(flag, value);
|
||||
for (size_t i=1; i<flags.size(); ++i)
|
||||
egf->setFlag(flags[i], value);
|
||||
idSet.erase(gid);
|
||||
}
|
||||
}
|
||||
geo = geo->clone();
|
||||
egf->setGeometry(geo);
|
||||
egf->setFlag(flag, value);
|
||||
for (size_t i=1; i<flags.size(); ++i)
|
||||
egf->setFlag(flags[i], value);
|
||||
if (value || flag != ExternalGeometryExtension::Frozen)
|
||||
update = true;
|
||||
touched = true;
|
||||
}
|
||||
|
||||
if(!touched)
|
||||
return -1;
|
||||
ExternalGeo.setValues(geos);
|
||||
if (update)
|
||||
rebuildExternalGeometry();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SketchObject::addGeometryState(const Constraint* cstr) const
|
||||
{
|
||||
const std::vector<Part::Geometry*>& vals = getInternalGeometry();
|
||||
@@ -4780,9 +4825,6 @@ int SketchObject::addSymmetric(const std::vector<int>& geoIdList, int refGeoId,
|
||||
}
|
||||
|
||||
// add the geometry
|
||||
// std::map<int, int> geoIdMap;
|
||||
// std::map<int, bool> isStartEndInverted;
|
||||
// std::vector<Part::Geometry*> newgeoVals(getInternalGeometry());
|
||||
std::vector<Part::Geometry*> symmetricVals = getSymmetric(geoIdList, geoIdMap, isStartEndInverted, refGeoId, refPosId);
|
||||
newgeoVals.insert(newgeoVals.end(), symmetricVals.begin(), symmetricVals.end());
|
||||
|
||||
@@ -5147,7 +5189,6 @@ std::vector<Part::Geometry*> SketchObject::getSymmetric(const std::vector<int>&
|
||||
auto* geosymaoe = static_cast<Part::GeomArcOfParabola*>(geosym);
|
||||
Base::Vector3d cp = geosymaoe->getCenter();
|
||||
|
||||
// double df= geosymaoe->getFocal();
|
||||
Base::Vector3d f1 = geosymaoe->getFocus();
|
||||
|
||||
Base::Vector3d sf1 =
|
||||
@@ -5342,7 +5383,6 @@ std::vector<Part::Geometry*> SketchObject::getSymmetric(const std::vector<int>&
|
||||
|
||||
geosymbsp->setPoles(poles);
|
||||
|
||||
// isStartEndInverted.insert(std::make_pair(geoId, false));
|
||||
}
|
||||
else if (geosym->is<Part::GeomPoint>()) {
|
||||
auto* geosympoint = static_cast<Part::GeomPoint*>(geosym);
|
||||
@@ -6878,7 +6918,6 @@ bool SketchObject::convertToNURBS(int GeoId)
|
||||
Base::StateLocker lock(managedoperation, true);
|
||||
|
||||
if (GeoId > getHighestCurveIndex()
|
||||
// || (GeoId < 0 && -GeoId > static_cast<int>(ExternalGeo.size())) || GeoId == -1
|
||||
|| (GeoId < 0 && -GeoId > static_cast<int>(ExternalGeo.getSize())) || GeoId == -1
|
||||
|| GeoId == -2)
|
||||
return false;
|
||||
@@ -7715,7 +7754,6 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName, boo
|
||||
// set the Link list.
|
||||
ExternalGeometry.setValues(Objects, SubElements);
|
||||
try {
|
||||
// rebuildExternalGeometry();
|
||||
rebuildExternalGeometry(defining, intersection);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
@@ -8014,7 +8052,6 @@ int SketchObject::attachExternal(
|
||||
}
|
||||
|
||||
auto geos = ExternalGeo.getValues();
|
||||
// auto geos = ExternalGeo;
|
||||
|
||||
std::vector<DocumentObject*> Objects = ExternalGeometry.getValues();
|
||||
auto itObj = Objects.begin();
|
||||
@@ -8026,7 +8063,7 @@ int SketchObject::attachExternal(
|
||||
|
||||
for(auto &key : externalGeoRef) {
|
||||
if (*itObj == Obj && *itSub == SubName){
|
||||
FC_ERR("Duplicdate external element reference in " << getFullName() << ": " << key);
|
||||
FC_ERR("Duplicate external element reference in " << getFullName() << ": " << key);
|
||||
return -1;
|
||||
}
|
||||
// detach old reference
|
||||
@@ -8062,7 +8099,6 @@ int SketchObject::attachExternal(
|
||||
std::vector<int> SketchObject::getRelatedGeometry(int GeoId) const {
|
||||
std::vector<int> res;
|
||||
if(GeoId>GeoEnum::RefExt || -GeoId-1>=ExternalGeo.getSize())
|
||||
// if(GeoId>GeoEnum::RefExt || -GeoId-1>=ExternalGeo.size())
|
||||
return res;
|
||||
auto geo = getGeometry(GeoId);
|
||||
if(!geo)
|
||||
@@ -8084,7 +8120,6 @@ std::vector<int> SketchObject::getRelatedGeometry(int GeoId) const {
|
||||
int SketchObject::syncGeometry(const std::vector<int> &geoIds) {
|
||||
bool touched = false;
|
||||
auto geos = ExternalGeo.getValues();
|
||||
// auto geos = ExternalGeo;
|
||||
std::set<int> idSet;
|
||||
for(int geoId : geoIds) {
|
||||
auto geo = getGeometry(geoId);
|
||||
@@ -8095,7 +8130,6 @@ int SketchObject::syncGeometry(const std::vector<int> &geoIds) {
|
||||
}
|
||||
for(int geoId : idSet) {
|
||||
if(geoId <= GeoEnum::RefExt && -geoId-1 < ExternalGeo.getSize()) {
|
||||
// if(geoId <= GeoEnum::RefExt && -geoId-1 < ExternalGeo.size()) {
|
||||
auto &geo = geos[-geoId-1];
|
||||
geo = geo->clone();
|
||||
ExternalGeometryFacade::getFacade(geo)->setFlag(ExternalGeometryExtension::Sync);
|
||||
@@ -8115,7 +8149,6 @@ const Part::Geometry* SketchObject::_getGeometry(int GeoId) const
|
||||
return geomlist[GeoId];
|
||||
}
|
||||
else if (GeoId < 0 && -GeoId-1 < ExternalGeo.getSize())
|
||||
// else if (GeoId < 0 && -GeoId-1 < ExternalGeo.size())
|
||||
return ExternalGeo[-GeoId-1];
|
||||
|
||||
return nullptr;
|
||||
@@ -8127,7 +8160,6 @@ int SketchObject::getCompleteGeometryIndex(int GeoId) const
|
||||
if (GeoId < int(Geometry.getSize()))
|
||||
return GeoId;
|
||||
}
|
||||
// else if (-GeoId <= int(ExternalGeo.size()))
|
||||
else if (-GeoId <= int(ExternalGeo.getSize()))
|
||||
return -GeoId - 1;
|
||||
|
||||
@@ -8136,7 +8168,6 @@ int SketchObject::getCompleteGeometryIndex(int GeoId) const
|
||||
|
||||
int SketchObject::getGeoIdFromCompleteGeometryIndex(int completeGeometryIndex) const
|
||||
{
|
||||
// int completeGeometryCount = int(Geometry.getSize() + ExternalGeo.size());
|
||||
int completeGeometryCount = int(Geometry.getSize() + ExternalGeo.getSize());
|
||||
|
||||
if (completeGeometryIndex < 0 || completeGeometryIndex >= completeGeometryCount)
|
||||
@@ -8258,14 +8289,14 @@ Part::Geometry* projectLine(const BRepAdaptor_Curve& curve, const Handle(Geom_Pl
|
||||
|
||||
// Project an edge to a line. Only works if the edge is planar and its plane is
|
||||
// perpendicular to the projection plane. This function is to work around OCC
|
||||
// normal projection bug which seems to only repsect the start and ending points
|
||||
// normal projection bug which seems to only respect the start and ending points
|
||||
// of an arc but disregarding any extreme points. OCC also has trouble handling
|
||||
// BSpline projection to a straight line. Although it does correctly projects
|
||||
// the line including extreme bounds, it will produce a BSpline with degree
|
||||
// more than one.
|
||||
//
|
||||
// The work around here is to use an aligned bounding box of the edge to get
|
||||
// the projection of the extremem points to construct the projected line.
|
||||
// the projection of the extreme points to construct the projected line.
|
||||
Part::Geometry* projectEdgeToLine(const TopoDS_Edge &edge,
|
||||
const Base::Placement& invPlm)
|
||||
{
|
||||
@@ -8342,7 +8373,7 @@ void getParameterRange(Handle(Geom_Curve) curve,
|
||||
// The reason of this function is because the first/last parameter reported
|
||||
// from some curve does not really corresponds to the first/last vertex of
|
||||
// the edge. I can only guess this is because the curve (in some cases) is
|
||||
// actually computed on demaond from surface (in BRepAdaptor_Curve maybe).
|
||||
// actually computed on demand from surface (in BRepAdaptor_Curve maybe).
|
||||
// And in the process, there is something off in tolerance causing the
|
||||
// derived parameter not matching the value corresponding to the position of
|
||||
// the actual vertex.
|
||||
@@ -8364,7 +8395,7 @@ void adjustParameterRange(const TopoDS_Edge &edge,
|
||||
// lower arc. Because projection orientation may swap the first and last
|
||||
// parameter of the original curve.
|
||||
//
|
||||
// We project the middel point of the original curve to the projected curve
|
||||
// We project the middle point of the original curve to the projected curve
|
||||
// to decide whether to flip the parameters.
|
||||
|
||||
Handle(Geom_Curve) origCurve = BRepAdaptor_Curve(edge).Curve().Curve();
|
||||
@@ -8589,13 +8620,13 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
auto obj = getDocument()->getObject(objName.c_str());
|
||||
if(!obj)
|
||||
continue;
|
||||
std::pair<std::string,std::string> elementName;
|
||||
App::ElementNamePair elementName;
|
||||
App::GeoFeature::resolveElement(obj,ref.c_str()+pos+1,elementName);
|
||||
if(elementName.second.size()
|
||||
&& !App::GeoFeature::hasMissingElement(elementName.second.c_str()))
|
||||
if(elementName.oldName.size()
|
||||
&& !App::GeoFeature::hasMissingElement(elementName.oldName.c_str()))
|
||||
{
|
||||
Objects.push_back(obj);
|
||||
SubElements.push_back(elementName.second);
|
||||
SubElements.push_back(elementName.oldName);
|
||||
keys.push_back(ref);
|
||||
}
|
||||
}
|
||||
@@ -8656,8 +8687,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
frozen = true;
|
||||
if(egf->testFlag(ExternalGeometryExtension::Sync))
|
||||
sync = true;
|
||||
// if (egf->testFlag(ExternalGeometryExtension::Intersection))
|
||||
// intersection = true;
|
||||
}
|
||||
}
|
||||
if(frozen && !sync) {
|
||||
@@ -8745,7 +8774,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
BRepAdaptor_Curve curve(edge);
|
||||
if (curve.GetType() == GeomAbs_Line) {
|
||||
geos.emplace_back(projectLine(curve, gPlane, invPlm));
|
||||
// ExternalGeo.push_back(projectLine(curve, gPlane, invPlm));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8763,7 +8791,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(refSubShape);
|
||||
BRepAdaptor_Curve curve(edge);
|
||||
if (curve.GetType() == GeomAbs_Line) {
|
||||
// ExternalGeo.push_back(projectLine(curve, gPlane, invPlm));
|
||||
geos.emplace_back(projectLine(curve, gPlane, invPlm));
|
||||
}
|
||||
else if (curve.GetType() == GeomAbs_Circle) {
|
||||
@@ -8787,7 +8814,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
gCircle->setCenter(Base::Vector3d(cnt.X(), cnt.Y(), cnt.Z()));
|
||||
|
||||
GeometryFacade::setConstruction(gCircle, true);
|
||||
// ExternalGeo.push_back(gCircle);
|
||||
geos.emplace_back(gCircle);
|
||||
}
|
||||
else {
|
||||
@@ -8797,7 +8823,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
hCircle, curve.FirstParameter(), curve.LastParameter());
|
||||
gArc->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(gArc, true);
|
||||
// ExternalGeo.push_back(gArc);
|
||||
geos.emplace_back(gArc);
|
||||
}
|
||||
}
|
||||
@@ -8917,7 +8942,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
|
||||
projectedSegment->setPoints(p1, p2);
|
||||
GeometryFacade::setConstruction(projectedSegment, true);
|
||||
// ExternalGeo.push_back(projectedSegment);
|
||||
geos.emplace_back(projectedSegment);
|
||||
}
|
||||
else {// general case, full circle
|
||||
@@ -8957,9 +8981,7 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Part::GeomEllipse* ellipse = new Part::GeomEllipse();
|
||||
ellipse->setHandle(curve);
|
||||
GeometryFacade::setConstruction(ellipse, true);
|
||||
|
||||
// ExternalGeo.push_back(ellipse);
|
||||
geos.emplace_back(ellipse);
|
||||
geos.emplace_back(ellipse);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9031,8 +9053,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Part::GeomCircle* circle = new Part::GeomCircle();
|
||||
circle->setHandle(curve);
|
||||
GeometryFacade::setConstruction(circle, true);
|
||||
|
||||
// ExternalGeo.push_back(circle);
|
||||
geos.emplace_back(circle);
|
||||
}
|
||||
else {
|
||||
@@ -9046,7 +9066,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Base::Vector3d(start.X(), start.Y(), start.Z()),
|
||||
Base::Vector3d(end.X(), end.Y(), end.Z()));
|
||||
GeometryFacade::setConstruction(projectedSegment, true);
|
||||
// ExternalGeo.push_back(projectedSegment);
|
||||
geos.emplace_back(projectedSegment);
|
||||
}
|
||||
else {
|
||||
@@ -9060,8 +9079,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Part::GeomEllipse* ellipse = new Part::GeomEllipse();
|
||||
ellipse->setHandle(curve);
|
||||
GeometryFacade::setConstruction(ellipse, true);
|
||||
|
||||
// ExternalGeo.push_back(ellipse);
|
||||
geos.emplace_back(ellipse);
|
||||
}
|
||||
}
|
||||
@@ -9089,14 +9106,12 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Base::Vector3d p = (p1 + p2) / 2;
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
GeometryFacade::setConstruction(point, true);
|
||||
// ExternalGeo.push_back(point);
|
||||
geos.emplace_back(point);
|
||||
}
|
||||
else {
|
||||
Part::GeomLineSegment* line = new Part::GeomLineSegment();
|
||||
line->setPoints(p1, p2);
|
||||
GeometryFacade::setConstruction(line, true);
|
||||
// ExternalGeo.push_back(line);
|
||||
geos.emplace_back(line);
|
||||
}
|
||||
}
|
||||
@@ -9112,7 +9127,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
circle->setCenter(Base::Vector3d(p.X(), p.Y(), p.Z()));
|
||||
|
||||
GeometryFacade::setConstruction(circle, true);
|
||||
// ExternalGeo.push_back(circle);
|
||||
geos.emplace_back(circle);
|
||||
}
|
||||
else {
|
||||
@@ -9124,7 +9138,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
projCurve.LastParameter());
|
||||
arc->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(arc, true);
|
||||
// ExternalGeo.push_back(arc);
|
||||
geos.emplace_back(arc);
|
||||
}
|
||||
}
|
||||
@@ -9151,14 +9164,12 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Base::Vector3d(center.X(), center.Y(), center.Z()));
|
||||
|
||||
GeometryFacade::setConstruction(circle, true);
|
||||
// ExternalGeo.push_back(circle);
|
||||
geos.emplace_back(circle);
|
||||
}
|
||||
else {
|
||||
Part::GeomBSplineCurve* bspline =
|
||||
new Part::GeomBSplineCurve(projCurve.BSpline());
|
||||
GeometryFacade::setConstruction(bspline, true);
|
||||
// ExternalGeo.push_back(bspline);
|
||||
geos.emplace_back(bspline);
|
||||
}
|
||||
}
|
||||
@@ -9180,7 +9191,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
hyperbola->setAngleXU(
|
||||
-xdir.AngleWithRef(xdirref.XDirection(), normal));
|
||||
GeometryFacade::setConstruction(hyperbola, true);
|
||||
// ExternalGeo.push_back(hyperbola);
|
||||
geos.emplace_back(hyperbola);
|
||||
}
|
||||
else {
|
||||
@@ -9193,7 +9203,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
projCurve.LastParameter());
|
||||
aoh->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(aoh, true);
|
||||
// ExternalGeo.push_back(aoh);
|
||||
geos.emplace_back(aoh);
|
||||
}
|
||||
}
|
||||
@@ -9214,7 +9223,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
parabola->setAngleXU(
|
||||
-xdir.AngleWithRef(xdirref.XDirection(), normal));
|
||||
GeometryFacade::setConstruction(parabola, true);
|
||||
// ExternalGeo.push_back(parabola);
|
||||
geos.emplace_back(parabola);
|
||||
}
|
||||
else {
|
||||
@@ -9227,7 +9235,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
projCurve.LastParameter());
|
||||
aop->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(aop, true);
|
||||
// ExternalGeo.push_back(aop);
|
||||
geos.emplace_back(aop);
|
||||
}
|
||||
}
|
||||
@@ -9246,7 +9253,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
Handle(Geom_Ellipse) curve = new Geom_Ellipse(e);
|
||||
ellipse->setHandle(curve);
|
||||
GeometryFacade::setConstruction(ellipse, true);
|
||||
// ExternalGeo.push_back(ellipse);
|
||||
geos.emplace_back(ellipse);
|
||||
}
|
||||
else {
|
||||
@@ -9258,7 +9264,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
projCurve.LastParameter());
|
||||
aoe->setHandle(tCurve);
|
||||
GeometryFacade::setConstruction(aoe, true);
|
||||
// ExternalGeo.push_back(aoe);
|
||||
geos.emplace_back(aoe);
|
||||
}
|
||||
}
|
||||
@@ -9283,7 +9288,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
|
||||
Part::GeomPoint* point = new Part::GeomPoint(p);
|
||||
GeometryFacade::setConstruction(point, true);
|
||||
// ExternalGeo.push_back(point);
|
||||
geos.emplace_back(point);
|
||||
} break;
|
||||
default:
|
||||
@@ -9300,8 +9304,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
FC_THROWM(Base::CADKernelError,"Failed to get intersection");
|
||||
Part::TopoShape intersectionShape(maker.Shape());
|
||||
auto edges = intersectionShape.getSubTopoShapes(TopAbs_EDGE);
|
||||
// for (const auto &s : edges)
|
||||
// importEdge(s.getShape());
|
||||
// Section of some face (e.g. sphere) produce more than one arcs
|
||||
// from the same circle. So we try to fit the arcs with a single
|
||||
// circle/arc.
|
||||
@@ -9322,8 +9324,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (const auto &s : intersectionShape.getSubShapes(TopAbs_VERTEX, TopAbs_EDGE))
|
||||
// importVertex(s);
|
||||
}
|
||||
|
||||
} catch (Base::Exception &e) {
|
||||
@@ -9353,7 +9353,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
if (intersection) {
|
||||
for(auto &geo : geos) {
|
||||
auto egf = ExternalGeometryFacade::getFacade(geo.get());
|
||||
// egf->setFlag(ExternalGeometryExtension::Intersection);
|
||||
egf->setFlag(ExternalGeometryExtension::Defining, defining);
|
||||
}
|
||||
} else if (defining && i+1==(int)Objects.size()) {
|
||||
@@ -9450,7 +9449,6 @@ void SketchObject::rebuildExternalGeometry(bool defining, bool addIntersection)
|
||||
void SketchObject::fixExternalGeometry(const std::vector<int> &geoIds) {
|
||||
std::set<int> idSet(geoIds.begin(),geoIds.end());
|
||||
auto geos = ExternalGeo.getValues();
|
||||
// auto geos = ExternalGeo;
|
||||
auto objs = ExternalGeometry.getValues();
|
||||
auto subs = ExternalGeometry.getSubValues();
|
||||
bool touched = false;
|
||||
@@ -9503,7 +9501,6 @@ void SketchObject::fixExternalGeometry(const std::vector<int> &geoIds) {
|
||||
std::vector<Part::Geometry*> SketchObject::getCompleteGeometry() const
|
||||
{
|
||||
std::vector<Part::Geometry*> vals = getInternalGeometry();
|
||||
// vals.insert(vals.end(), ExternalGeo.rbegin(), ExternalGeo.rend());// in reverse order
|
||||
const auto &geos = getExternalGeometry();
|
||||
vals.insert(vals.end(), geos.rbegin(), geos.rend()); // in reverse order
|
||||
return vals;
|
||||
@@ -9512,13 +9509,11 @@ std::vector<Part::Geometry*> SketchObject::getCompleteGeometry() const
|
||||
GeoListFacade SketchObject::getGeoListFacade() const
|
||||
{
|
||||
std::vector<GeometryFacadeUniquePtr> facade;
|
||||
// facade.reserve(Geometry.getSize() + ExternalGeo.size());
|
||||
facade.reserve(Geometry.getSize() + ExternalGeo.getSize());
|
||||
|
||||
for (auto geo : Geometry.getValues())
|
||||
facade.push_back(GeometryFacade::getFacade(geo));
|
||||
|
||||
// for (auto rit = ExternalGeo.rbegin(); rit != ExternalGeo.rend(); rit++)
|
||||
const auto &externalGeos = ExternalGeo.getValues();
|
||||
for(auto rit = externalGeos.rbegin(); rit != externalGeos.rend(); rit++)
|
||||
facade.push_back(GeometryFacade::getFacade(*rit));
|
||||
@@ -10279,14 +10274,7 @@ static inline bool checkMigration(Part::PropertyGeometryList &prop)
|
||||
|
||||
void SketchObject::onChanged(const App::Property* prop)
|
||||
{
|
||||
// if (isRestoring() && prop == &Geometry) {
|
||||
// std::vector<Part::Geometry*> geom = Geometry.getValues();
|
||||
// std::vector<Part::Geometry*> supportedGeom = supportedGeometry(geom);
|
||||
// // To keep upward compatibility ignore unsupported geometry types
|
||||
// if (supportedGeom.size() != geom.size()) {
|
||||
// Geometry.setValues(supportedGeom);
|
||||
// return;
|
||||
// }
|
||||
|
||||
if (prop == &Geometry) {
|
||||
if (isRestoring() && checkMigration(Geometry)) {
|
||||
// Construction migration to extension
|
||||
@@ -10308,6 +10296,21 @@ void SketchObject::onChanged(const App::Property* prop)
|
||||
}
|
||||
}
|
||||
}
|
||||
geoMap.clear();
|
||||
const auto &vals = getInternalGeometry();
|
||||
for(long i=0;i<(long)vals.size();++i) {
|
||||
auto geo = vals[i];
|
||||
auto gf = GeometryFacade::getFacade(geo);
|
||||
if(!gf->getId())
|
||||
gf->setId(++geoLastId);
|
||||
else if(gf->getId() > geoLastId)
|
||||
geoLastId = gf->getId();
|
||||
while(!geoMap.insert(std::make_pair(gf->getId(),i)).second) {
|
||||
FC_WARN("duplicate geometry id " << gf->getId() << " -> " << geoLastId+1);
|
||||
gf->setId(++geoLastId);
|
||||
}
|
||||
}
|
||||
updateGeoHistory();
|
||||
}
|
||||
|
||||
auto doc = getDocument();
|
||||
@@ -10546,7 +10549,7 @@ void SketchObject::updateGeometryRefs() {
|
||||
std::unordered_map<std::string, int> legacyMap;
|
||||
for(int i=0;i<(int)objs.size();++i) {
|
||||
auto obj = objs[i];
|
||||
const std::string &sub=shadows[i].first.size()?shadows[i].first:subs[i];
|
||||
const std::string &sub=shadows[i].newName.size()?shadows[i].newName:subs[i];
|
||||
externalGeoRef.emplace_back(obj->getNameInDocument());
|
||||
auto &key = externalGeoRef.back();
|
||||
key += '.';
|
||||
@@ -11806,10 +11809,10 @@ std::string SketchObject::getGeometryReference(int GeoId) const {
|
||||
if(!obj)
|
||||
return ref;
|
||||
|
||||
std::pair<std::string,std::string> elementName;
|
||||
App::ElementNamePair elementName;
|
||||
App::GeoFeature::resolveElement(obj,ref.c_str()+pos+1,elementName);
|
||||
if(elementName.second.size())
|
||||
return objName + "." + elementName.second;
|
||||
if(elementName.oldName.size())
|
||||
return objName + "." + elementName.oldName;
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "GeometryFacade.h"
|
||||
#include "Sketch.h"
|
||||
|
||||
#include "SketchGeometryExtension.h"
|
||||
#include "ExternalGeometryExtension.h"
|
||||
|
||||
namespace Sketcher
|
||||
{
|
||||
@@ -70,8 +72,6 @@ public:
|
||||
Part ::PropertyGeometryList ExternalGeo;
|
||||
App ::PropertyBool FullyConstrained;
|
||||
App ::PropertyPrecision ArcFitTolerance;
|
||||
// App ::PropertyInteger ExternalBSplineMaxDegree;
|
||||
// App ::PropertyPrecision ExternalBSplineTolerance;
|
||||
Part ::PropertyPartShape InternalShape;
|
||||
App ::PropertyPrecision InternalTolerance;
|
||||
App ::PropertyBool MakeInternals;
|
||||
@@ -213,7 +213,6 @@ public:
|
||||
typename GeometryT = Part::Geometry,
|
||||
typename = typename std::enable_if<
|
||||
std::is_base_of<Part::Geometry, typename std::decay<GeometryT>::type>::value>::type>
|
||||
// const GeometryT* getGeometry(int GeoId) const;
|
||||
const GeometryT* getGeometry(int GeoId) const
|
||||
{
|
||||
return static_cast<const GeometryT*>(_getGeometry(GeoId));
|
||||
@@ -229,7 +228,6 @@ public:
|
||||
/// returns a list of projected external geometries
|
||||
const std::vector<Part::Geometry*>& getExternalGeometry() const
|
||||
{
|
||||
// return ExternalGeo;
|
||||
return ExternalGeo.getValues();
|
||||
}
|
||||
/// rebuilds external geometry (projection onto the sketch plane)
|
||||
@@ -237,7 +235,6 @@ public:
|
||||
/// returns the number of external Geometry entities
|
||||
int getExternalGeometryCount() const
|
||||
{
|
||||
// return ExternalGeo.size();
|
||||
return ExternalGeo.getSize();
|
||||
}
|
||||
/// auto fix external geometry references
|
||||
@@ -751,6 +748,8 @@ public:
|
||||
|
||||
std::string convertSubName(const Data::IndexedName&, bool postfix = true) const;
|
||||
|
||||
Data::IndexedName shapeTypeFromGeoId(int GeoId, PointPos pos = Sketcher::PointPos::none) const;
|
||||
|
||||
App::ElementNamePair getElementName(const char* name, ElementNameType type) const override;
|
||||
|
||||
bool isPerformingInternalTransaction() const
|
||||
@@ -824,13 +823,17 @@ public: // geometry extension functionalities for single element sketch object
|
||||
int getGeometryId(int GeoId, long& id) const;
|
||||
|
||||
protected:
|
||||
// Only the first flag is toggled, the rest of the flags is set or cleared following the first
|
||||
// flag.
|
||||
int toggleExternalGeometryFlag(const std::vector<int>& geoIds,
|
||||
const std::vector<ExternalGeometryExtension::Flag>& flags);
|
||||
|
||||
void buildShape();
|
||||
/// get called by the container when a property has changed
|
||||
void onChanged(const App::Property* /*prop*/) override;
|
||||
void onDocumentRestored() override;
|
||||
void restoreFinished() override;
|
||||
|
||||
void buildShape();
|
||||
|
||||
std::string validateExpression(const App::ObjectIdentifier& path,
|
||||
std::shared_ptr<const App::Expression> expr);
|
||||
|
||||
@@ -924,8 +927,6 @@ private:
|
||||
/// Flag to allow carbon copy from misaligned geometry
|
||||
bool allowUnaligned;
|
||||
|
||||
// std::vector<Part::Geometry*> ExternalGeo;
|
||||
|
||||
std::vector<int> VertexId2GeoId;
|
||||
std::vector<PointPos> VertexId2PosId;
|
||||
|
||||
@@ -1039,22 +1040,6 @@ inline int SketchObject::moveTemporaryPoint(int geoId,
|
||||
return solvedSketch.movePoint(geoId, pos, toPoint, relative);
|
||||
}
|
||||
|
||||
// template<typename GeometryT, typename>
|
||||
// const GeometryT* SketchObject::getGeometry(int GeoId) const
|
||||
//{
|
||||
// if (GeoId >= 0) {
|
||||
// const std::vector<Part::Geometry*>& geomlist = getInternalGeometry();
|
||||
// if (GeoId < int(geomlist.size())) {
|
||||
// return static_cast<GeometryT*>(geomlist[GeoId]);
|
||||
// }
|
||||
// }
|
||||
//// else if (-GeoId <= int(ExternalGeo.size())) {
|
||||
// else if (-GeoId <= int(ExternalGeo.getSize())) {
|
||||
// return static_cast<GeometryT*>(ExternalGeo[-GeoId - 1]);
|
||||
// }
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
|
||||
using SketchObjectPython = App::FeaturePythonT<SketchObject>;
|
||||
|
||||
|
||||
@@ -2884,41 +2884,38 @@ void ViewProviderSketch::drawEditMarkers(const std::vector<Base::Vector2d>& Edit
|
||||
editCoinManager->drawEditMarkers(EditMarkers, augmentationlevel);
|
||||
}
|
||||
|
||||
void ViewProviderSketch::updateData(const App::Property* prop)
|
||||
{
|
||||
void ViewProviderSketch::updateData(const App::Property* prop) {
|
||||
ViewProvider2DObject::updateData(prop);
|
||||
|
||||
// In the case of an undo/redo transaction, updateData is triggered by
|
||||
// SketchObject::onUndoRedoFinished() in the solve() In the case of an internal transaction,
|
||||
// touching the geometry results in a call to updateData.
|
||||
if (isInEditMode() && !getSketchObject()->getDocument()->isPerformingTransaction()
|
||||
&& !getSketchObject()->isPerformingInternalTransaction()
|
||||
&& (prop == &(getSketchObject()->Geometry) || prop == &(getSketchObject()->Constraints))) {
|
||||
if (prop != &getSketchObject()->Constraints)
|
||||
signalElementsChanged();
|
||||
}
|
||||
|
||||
// At this point, we do not need to solve the Sketch
|
||||
// If we are adding geometry an update can be triggered before the sketch is actually
|
||||
// solved. Because a solve is mandatory to any addition (at least to update the DoF of the
|
||||
// solver), only when the solver geometry is the same in number than the sketch geometry an
|
||||
// update should trigger a redraw. This reduces even more the number of redraws per
|
||||
// insertion of geometry
|
||||
void ViewProviderSketch::slotSolverUpdate()
|
||||
{
|
||||
if (!isInEditMode() )
|
||||
return;
|
||||
|
||||
// solver information is also updated when no matching geometry, so that if a solving fails
|
||||
// this failed solving info is presented to the user
|
||||
UpdateSolverInformation();// just update the solver window with the last SketchObject
|
||||
// solving information
|
||||
// At this point, we do not need to solve the Sketch
|
||||
// If we are adding geometry an update can be triggered before the sketch is actually
|
||||
// solved. Because a solve is mandatory to any addition (at least to update the DoF of the
|
||||
// solver), only when the solver geometry is the same in number than the sketch geometry an
|
||||
// update should trigger a redraw. This reduces even more the number of redraws per
|
||||
// insertion of geometry
|
||||
|
||||
if (getSketchObject()->getExternalGeometryCount()
|
||||
+ getSketchObject()->getHighestCurveIndex() + 1
|
||||
== getSolvedSketch().getGeometrySize()) {
|
||||
Gui::MDIView* mdi = Gui::Application::Instance->editDocument()->getActiveView();
|
||||
if (mdi->isDerivedFrom(Gui::View3DInventor::getClassTypeId()))
|
||||
draw(false, true);
|
||||
// solver information is also updated when no matching geometry, so that if a solving fails
|
||||
// this failed solving info is presented to the user
|
||||
UpdateSolverInformation();// just update the solver window with the last SketchObject
|
||||
// solving information
|
||||
|
||||
signalConstraintsChanged();
|
||||
}
|
||||
if (getSketchObject()->getExternalGeometryCount()
|
||||
+ getSketchObject()->getHighestCurveIndex() + 1
|
||||
== getSolvedSketch().getGeometrySize()) {
|
||||
Gui::MDIView* mdi = Gui::Application::Instance->editDocument()->getActiveView();
|
||||
if (mdi->isDerivedFrom(Gui::View3DInventor::getClassTypeId()))
|
||||
draw(false, true);
|
||||
|
||||
if (prop != &getSketchObject()->Constraints)
|
||||
signalElementsChanged();
|
||||
signalConstraintsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3124,6 +3121,15 @@ bool ViewProviderSketch::setEdit(int ModNum)
|
||||
getSketchObject()->validateExternalLinks();
|
||||
}
|
||||
|
||||
//NOLINTBEGIN
|
||||
connectUndoDocument = getDocument()->signalUndoDocument.connect(
|
||||
std::bind(&ViewProviderSketch::slotUndoDocument, this, sp::_1));
|
||||
connectRedoDocument = getDocument()->signalRedoDocument.connect(
|
||||
std::bind(&ViewProviderSketch::slotRedoDocument, this, sp::_1));
|
||||
connectSolverUpdate = getSketchObject()
|
||||
->signalSolverUpdate.connect(boost::bind(&ViewProviderSketch::slotSolverUpdate, this));
|
||||
//NOLINTEND
|
||||
|
||||
// There are geometry extensions introduced by the solver and geometry extensions introduced by
|
||||
// the viewprovider.
|
||||
// 1. It is important that the solver has geometry with updated extensions.
|
||||
@@ -3139,13 +3145,6 @@ bool ViewProviderSketch::setEdit(int ModNum)
|
||||
// a draw(true) via ViewProvider::UpdateData.
|
||||
getSketchObject()->solve(true);
|
||||
|
||||
//NOLINTBEGIN
|
||||
connectUndoDocument = getDocument()->signalUndoDocument.connect(
|
||||
std::bind(&ViewProviderSketch::slotUndoDocument, this, sp::_1));
|
||||
connectRedoDocument = getDocument()->signalRedoDocument.connect(
|
||||
std::bind(&ViewProviderSketch::slotRedoDocument, this, sp::_1));
|
||||
//NOLINTEND
|
||||
|
||||
// Enable solver initial solution update while dragging.
|
||||
getSketchObject()->setRecalculateInitialSolutionWhileMovingPoint(
|
||||
viewProviderParameters.recalculateInitialSolutionWhileDragging);
|
||||
@@ -3355,6 +3354,7 @@ void ViewProviderSketch::unsetEdit(int ModNum)
|
||||
|
||||
connectUndoDocument.disconnect();
|
||||
connectRedoDocument.disconnect();
|
||||
connectSolverUpdate.disconnect();
|
||||
|
||||
// when pressing ESC make sure to close the dialog
|
||||
Gui::Control().closeDialog();
|
||||
|
||||
@@ -745,6 +745,7 @@ protected:
|
||||
//@{
|
||||
void slotUndoDocument(const Gui::Document&);
|
||||
void slotRedoDocument(const Gui::Document&);
|
||||
void slotSolverUpdate();
|
||||
void forceUpdateData();
|
||||
//@}
|
||||
|
||||
@@ -924,6 +925,7 @@ private:
|
||||
private:
|
||||
boost::signals2::connection connectUndoDocument;
|
||||
boost::signals2::connection connectRedoDocument;
|
||||
boost::signals2::connection connectSolverUpdate;
|
||||
|
||||
// modes while sketching
|
||||
SketchMode Mode;
|
||||
|
||||
@@ -537,6 +537,113 @@ class TestSketcherSolver(unittest.TestCase):
|
||||
self.assertEqual(len(hole.Shape.Edges), 32)
|
||||
self.assertEqual(len(sketch2.ExternalGeometry), 1)
|
||||
|
||||
def testSaveLoadWithExternalGeometryReference(self):
|
||||
body = self.Doc.addObject("PartDesign::Body", "Body")
|
||||
sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch")
|
||||
CreateRectangleSketch(sketch, (0, 0), (30, 30))
|
||||
pad = self.Doc.addObject("PartDesign::Pad", "Pad")
|
||||
pad.Profile = sketch
|
||||
sketch1 = self.Doc.addObject("Sketcher::SketchObject", "Sketch1")
|
||||
body.addObject(sketch)
|
||||
body.addObject(pad)
|
||||
body.addObject(sketch1)
|
||||
self.Doc.recompute()
|
||||
sketch1.addExternal("Pad", "Edge12")
|
||||
self.Doc.recompute()
|
||||
|
||||
# Try changing it before the save
|
||||
sketch = self.Doc.getObject("Sketch")
|
||||
g1 = sketch.Constraints[11].First
|
||||
d1 = sketch.Constraints[11].Value
|
||||
sketch.delConstraint(11)
|
||||
sketch.addConstraint(Sketcher.Constraint("Distance", g1, d1 - 1.0))
|
||||
self.Doc.recompute()
|
||||
|
||||
filename = self.Doc.Name + ".FCStd"
|
||||
self.Doc.saveAs(filename)
|
||||
FreeCAD.closeDocument(self.Doc.Name)
|
||||
self.Doc = FreeCAD.openDocument(filename)
|
||||
pad = self.Doc.getObject("Pad")
|
||||
self.Doc.recompute()
|
||||
pad = self.Doc.getObject("Pad")
|
||||
|
||||
sketch = self.Doc.getObject("Sketch")
|
||||
g1 = sketch.Constraints[11].First
|
||||
d1 = sketch.Constraints[11].Value
|
||||
sketch.delConstraint(11)
|
||||
sketch.addConstraint(Sketcher.Constraint("Distance", g1, d1 - 1.0))
|
||||
self.Doc.recompute()
|
||||
|
||||
pad = self.Doc.getObject("Pad")
|
||||
# TODO: Assert some stuff when the bug is fixed
|
||||
# self.assertEqual(pad.Shape.ElementMapSize,0)
|
||||
# self.assertNotNull(pad.Shape.ElementReverseMap["Edge12"])
|
||||
|
||||
def testTNPExternalGeometryStored(self):
|
||||
# Arrange
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
sketch = self.Doc.addObject("Sketcher::SketchObject", "Sketch")
|
||||
CreateRectangleSketch(sketch, (0, 0), (30, 30))
|
||||
sketch1 = self.Doc.addObject("Sketcher::SketchObject", "Sketch1")
|
||||
pad = self.Doc.addObject("PartDesign::Pad", "Pad")
|
||||
pad.Profile = sketch
|
||||
self.Doc.recompute()
|
||||
# sketch1.addExternal("Sketch", "Edge3")
|
||||
sketch1.addExternal("Pad", "Edge12")
|
||||
self.Doc.recompute()
|
||||
# Act
|
||||
root = ET.fromstring("<all>" + sketch1.Content + "</all>")
|
||||
# Can't use != in an xpath because it wasn't added until python 3.10.
|
||||
# "*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref!='']"
|
||||
extRefs = root.findall(
|
||||
"*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref='']"
|
||||
)
|
||||
extRefsAll = root.findall(
|
||||
"*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref]"
|
||||
)
|
||||
# Assert
|
||||
self.assertEqual(len(extRefs), 2)
|
||||
self.assertEqual(len(extRefsAll), 3)
|
||||
self.assertEqual(root.tag, "all")
|
||||
# Act
|
||||
filename = self.Doc.Name + ".FCStd"
|
||||
self.Doc.saveAs(filename)
|
||||
FreeCAD.closeDocument(self.Doc.Name)
|
||||
self.Doc = FreeCAD.openDocument(filename)
|
||||
# Assert
|
||||
root = ET.fromstring("<all>" + self.Doc.getObject("Sketch1").Content + "</all>")
|
||||
extRefs = root.findall(
|
||||
"*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref='']"
|
||||
)
|
||||
extRefsAll = root.findall(
|
||||
"*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref]"
|
||||
)
|
||||
self.assertEqual(len(extRefs), 2)
|
||||
self.assertEqual(len(extRefsAll), 3)
|
||||
self.assertEqual(root.tag, "all")
|
||||
# Act
|
||||
sketch = self.Doc.getObject("Sketch")
|
||||
g1 = sketch.Constraints[11].First
|
||||
d1 = sketch.Constraints[11].Value
|
||||
sketch.delConstraint(11)
|
||||
sketch.addConstraint(Sketcher.Constraint("Distance", g1, d1 - 1.0))
|
||||
self.Doc.recompute()
|
||||
# Assert
|
||||
root = ET.fromstring("<all>" + self.Doc.getObject("Sketch1").Content + "</all>")
|
||||
extRefs = root.findall(
|
||||
"*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref='']"
|
||||
)
|
||||
extRefsAll = root.findall(
|
||||
"*/*[@name='ExternalGeo']//*/[@type='Sketcher::ExternalGeometryExtension']/[@Ref]"
|
||||
)
|
||||
self.assertEqual(len(extRefs), 2)
|
||||
self.assertEqual(len(extRefsAll), 3)
|
||||
self.assertEqual(root.tag, "all")
|
||||
|
||||
# TODO other tests:
|
||||
# getHigherElement
|
||||
|
||||
def assertSuccessfulSolve(self, sketch, msg=None):
|
||||
status = sketch.solve()
|
||||
# TODO: can we get the solver's messages somehow to improve the message?
|
||||
|
||||
@@ -266,29 +266,29 @@ TEST_F(SketchObjectTest, testGetElementName)
|
||||
// unless it's Export, we are really just testing the superclass App::GeoFeature::getElementName
|
||||
// call.
|
||||
auto forward_normal_name =
|
||||
getObject()->getElementName("g39;SKT", App::GeoFeature::ElementNameType::Normal);
|
||||
getObject()->getElementName("g1;SKT", App::GeoFeature::ElementNameType::Normal);
|
||||
auto reverse_normal_name =
|
||||
getObject()->getElementName("Vertex2", App::GeoFeature::ElementNameType::Normal);
|
||||
auto reverse_export_name =
|
||||
getObject()->getElementName("Vertex1", App::GeoFeature::ElementNameType::Export);
|
||||
auto map = getObject()->Shape.getShape().getElementMap();
|
||||
ASSERT_EQ(map.size(), 3);
|
||||
EXPECT_STREQ(map[0].name.toString().c_str(), "g39;SKT");
|
||||
EXPECT_STREQ(map[0].name.toString().c_str(), "g1;SKT");
|
||||
EXPECT_EQ(map[0].index.toString(), "Edge1");
|
||||
// Assert
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_STREQ(forward_normal_name.newName.c_str(), "");
|
||||
EXPECT_STREQ(forward_normal_name.oldName.c_str(), "g39;SKT");
|
||||
EXPECT_STREQ(forward_normal_name.oldName.c_str(), "g1;SKT");
|
||||
EXPECT_STREQ(reverse_normal_name.newName.c_str(), "");
|
||||
EXPECT_STREQ(reverse_normal_name.oldName.c_str(), "Vertex2");
|
||||
EXPECT_STREQ(reverse_export_name.newName.c_str(), ";g39v1;SKT.Vertex1");
|
||||
EXPECT_STREQ(reverse_export_name.newName.c_str(), ";g1v1;SKT.Vertex1");
|
||||
EXPECT_STREQ(reverse_export_name.oldName.c_str(), "Vertex1");
|
||||
#else
|
||||
EXPECT_STREQ(forward_normal_name.newName.c_str(), ";g39;SKT.Edge1");
|
||||
EXPECT_STREQ(forward_normal_name.newName.c_str(), ";g1;SKT.Edge1");
|
||||
EXPECT_STREQ(forward_normal_name.oldName.c_str(), "Edge1");
|
||||
EXPECT_STREQ(reverse_normal_name.newName.c_str(), ";g39v2;SKT.Vertex2");
|
||||
EXPECT_STREQ(reverse_normal_name.newName.c_str(), ";g1v2;SKT.Vertex2");
|
||||
EXPECT_STREQ(reverse_normal_name.oldName.c_str(), "Vertex2");
|
||||
EXPECT_STREQ(reverse_export_name.newName.c_str(), ";g39v1;SKT.Vertex1");
|
||||
EXPECT_STREQ(reverse_export_name.newName.c_str(), ";g1v1;SKT.Vertex1");
|
||||
EXPECT_STREQ(reverse_export_name.oldName.c_str(), "Vertex1");
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user