Merge pull request #15509 from bgbsww/bgbsww-toponamingSaveRestore8
Toponaming: Bring in ExportGeo and refmaps
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;
|
||||
|
||||
@@ -43,23 +43,38 @@
|
||||
#include <QDateTime>
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/algorithm/string/regex.hpp>
|
||||
#include <boost/format.hpp>
|
||||
#include <boost/geometry/geometries/register/point.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost_geometry.hpp>
|
||||
|
||||
// OpenCasCade
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <BRepAlgoAPI_Section.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_MakeVertex.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRepOffsetAPI_NormalProjection.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <GCPnts_AbscissaPoint.hxx>
|
||||
#include <GC_MakeArcOfCircle.hxx>
|
||||
#include <GC_MakeCircle.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
#include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
#include <GeomConvert_BSplineCurveKnotSplitting.hxx>
|
||||
#include <GeomLProp_CLProps.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_Circle.hxx>
|
||||
#include <Geom_Ellipse.hxx>
|
||||
@@ -74,6 +89,7 @@
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,8 @@
|
||||
#include "GeometryFacade.h"
|
||||
#include "Sketch.h"
|
||||
|
||||
#include "SketchGeometryExtension.h"
|
||||
#include "ExternalGeometryExtension.h"
|
||||
|
||||
namespace Sketcher
|
||||
{
|
||||
@@ -66,8 +68,12 @@ public:
|
||||
Part ::PropertyGeometryList Geometry;
|
||||
Sketcher::PropertyConstraintList Constraints;
|
||||
App ::PropertyLinkSubList ExternalGeometry;
|
||||
App ::PropertyLinkListHidden Exports;
|
||||
Part ::PropertyGeometryList ExternalGeo;
|
||||
App ::PropertyBool FullyConstrained;
|
||||
App ::PropertyPrecision ArcFitTolerance;
|
||||
Part ::PropertyPartShape InternalShape;
|
||||
App ::PropertyPrecision InternalTolerance;
|
||||
App ::PropertyBool MakeInternals;
|
||||
/** @name methods override Feature */
|
||||
//@{
|
||||
@@ -172,16 +178,31 @@ public:
|
||||
/// Carbon copy another sketch geometry and constraints
|
||||
int carbonCopy(App::DocumentObject* pObj, bool construction = true);
|
||||
/// add an external geometry reference
|
||||
int addExternal(App::DocumentObject* Obj, const char* SubName);
|
||||
int addExternal(App::DocumentObject* Obj,
|
||||
const char* SubName,
|
||||
bool defining = false,
|
||||
bool intersection = false);
|
||||
/** delete external
|
||||
* ExtGeoId >= 0 with 0 corresponding to the first user defined
|
||||
* external geometry
|
||||
*/
|
||||
int delExternal(int ExtGeoId);
|
||||
int delExternal(const std::vector<int>& ExtGeoIds);
|
||||
/// attach a link reference to an external geometry
|
||||
int
|
||||
attachExternal(const std::vector<int>& geoIds, App::DocumentObject* Obj, const char* SubName);
|
||||
int detachExternal(const std::vector<int>& geoIds);
|
||||
|
||||
/** deletes all external geometry */
|
||||
int delAllExternal();
|
||||
|
||||
const Part::Geometry* _getGeometry(int GeoId) const;
|
||||
int setGeometry(int GeoId, const Part::Geometry*);
|
||||
/// returns GeoId of all geometries projected from the same external geometry reference
|
||||
std::vector<int> getRelatedGeometry(int GeoId) const;
|
||||
/// Sync frozen external geometries
|
||||
int syncGeometry(const std::vector<int>& geoIds);
|
||||
|
||||
/** returns a pointer to a given Geometry index, possible indexes are:
|
||||
* id>=0 for user defined geometries,
|
||||
* id==-1 for the horizontal sketch axis,
|
||||
@@ -192,7 +213,10 @@ 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));
|
||||
}
|
||||
|
||||
std::unique_ptr<const GeometryFacade> getGeometryFacade(int GeoId) const;
|
||||
|
||||
@@ -204,15 +228,17 @@ 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)
|
||||
void rebuildExternalGeometry();
|
||||
void rebuildExternalGeometry(bool defining = false, bool intersection = false);
|
||||
/// returns the number of external Geometry entities
|
||||
int getExternalGeometryCount() const
|
||||
{
|
||||
return ExternalGeo.size();
|
||||
return ExternalGeo.getSize();
|
||||
}
|
||||
/// auto fix external geometry references
|
||||
void fixExternalGeometry(const std::vector<int>& geoIds = {});
|
||||
|
||||
/// retrieves a vector containing both normal and external Geometry (including the sketch axes)
|
||||
std::vector<Part::Geometry*> getCompleteGeometry() const;
|
||||
@@ -516,6 +542,9 @@ public:
|
||||
unsigned int getMemSize() const override;
|
||||
void Save(Base::Writer& /*writer*/) const override;
|
||||
void Restore(Base::XMLReader& /*reader*/) override;
|
||||
void handleChangedPropertyType(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
App::Property* prop) override;
|
||||
|
||||
/// returns the number of construction lines (to be used as axes)
|
||||
int getAxisCount() const override;
|
||||
@@ -704,6 +733,9 @@ public:
|
||||
return geoIdFromShapeType(shapetype, geoId, posId);
|
||||
}
|
||||
|
||||
/// Return a human friendly element reference of an external geometry
|
||||
std::string getGeometryReference(int GeoId) const;
|
||||
|
||||
std::string convertSubName(const char* subname, bool postfix = true) const;
|
||||
|
||||
std::string convertSubName(const std::string& subname, bool postfix = true) const
|
||||
@@ -716,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
|
||||
@@ -789,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);
|
||||
|
||||
@@ -809,6 +847,8 @@ protected:
|
||||
std::vector<Part::Geometry*>
|
||||
supportedGeometry(const std::vector<Part::Geometry*>& geoList) const;
|
||||
|
||||
void updateGeoHistory();
|
||||
void generateId(Part::Geometry* geo);
|
||||
|
||||
/*!
|
||||
\brief Transfer constraints on lines being filleted.
|
||||
@@ -827,6 +867,14 @@ protected:
|
||||
// check whether constraint may be changed driving status
|
||||
int testDrivingChange(int ConstrId, bool isdriving);
|
||||
|
||||
void initExternalGeo();
|
||||
|
||||
void onUpdateElementReference(const App::Property*) override;
|
||||
|
||||
void delExternalPrivate(const std::set<long>& ids, bool removeReference);
|
||||
|
||||
void updateGeometryRefs();
|
||||
|
||||
void onUndoRedoFinished() override;
|
||||
|
||||
// migration functions
|
||||
@@ -879,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;
|
||||
|
||||
@@ -932,9 +978,30 @@ private:
|
||||
|
||||
bool internaltransaction;
|
||||
|
||||
// indicates whether changes to properties are the deed of SketchObject or not (for input
|
||||
// validation)
|
||||
bool managedoperation;
|
||||
bool managedoperation; // indicates whether changes to properties are the deed of SketchObject
|
||||
// or not (for input validation)
|
||||
|
||||
// mapping from ExternalGeometry[*] to ExternalGeo[*].Id
|
||||
// Some external geometry may generate more than one projection
|
||||
std::map<std::string, std::vector<long>> externalGeoRefMap;
|
||||
bool updateGeoRef = false;
|
||||
|
||||
// backup of ExternalGeometry in case of element reference change
|
||||
std::vector<std::string> externalGeoRef;
|
||||
|
||||
// mapping from ExternalGeo[*].Id to index of ExternalGeo
|
||||
std::map<long, int> externalGeoMap;
|
||||
|
||||
// mapping from Geometry[*].Id to index of Geometry
|
||||
std::map<long, int> geoMap;
|
||||
|
||||
int geoHistoryLevel;
|
||||
std::vector<long> geoIdHistory;
|
||||
long geoLastId;
|
||||
|
||||
class GeoHistory;
|
||||
std::unique_ptr<GeoHistory> geoHistory;
|
||||
|
||||
mutable std::map<std::string, std::string> internalElementMap;
|
||||
};
|
||||
|
||||
@@ -973,24 +1040,10 @@ 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())) {
|
||||
return static_cast<GeometryT*>(ExternalGeo[-GeoId - 1]);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
using SketchObjectPython = App::FeaturePythonT<SketchObject>;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
} // namespace Sketcher
|
||||
|
||||
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -260,35 +260,45 @@ TEST_F(SketchObjectTest, testGetElementName)
|
||||
Base::Vector3d p1(0.0, 0.0, 0.0), p2(1.0, 0.0, 0.0);
|
||||
std::unique_ptr<Part::Geometry> geoline(new Part::GeomLineSegment());
|
||||
static_cast<Part::GeomLineSegment*>(geoline.get())->setPoints(p1, p2);
|
||||
getObject()->addGeometry(geoline.get());
|
||||
auto id = getObject()->addGeometry(geoline.get());
|
||||
long tag;
|
||||
getObject()->getGeometryId(id, tag); // We need to look up the tag that got assigned
|
||||
std::ostringstream oss;
|
||||
oss << "g" << tag;
|
||||
auto tagName = oss.str();
|
||||
getObject()->recomputeFeature(); // or ->execute()
|
||||
// Act
|
||||
// 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((tagName + ";SKT").c_str(),
|
||||
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(), (tagName + ";SKT").c_str());
|
||||
EXPECT_EQ(map[0].index.toString(), "Edge1");
|
||||
EXPECT_STREQ(map[1].name.toString().c_str(), (tagName + "v1;SKT").c_str());
|
||||
EXPECT_EQ(map[1].index.toString(), "Vertex1");
|
||||
EXPECT_STREQ(map[2].name.toString().c_str(), (tagName + "v2;SKT").c_str());
|
||||
EXPECT_EQ(map[2].index.toString(), "Vertex2");
|
||||
// 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(), (";" + tagName + ";SKT.Edge1").c_str());
|
||||
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(), (";" + tagName + "v2;SKT.Vertex2").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(), (";" + tagName + "v1;SKT.Vertex1").c_str());
|
||||
EXPECT_STREQ(reverse_export_name.oldName.c_str(), "Vertex1");
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user