Merge pull request #13387 from bgbsww/bgbsww-toponamingPD5FeaturePad

Toponaming/Part Transfer more python ElementMapVersion and add feature pad testing
This commit is contained in:
Chris Hennes
2024-04-14 16:06:40 -05:00
committed by GitHub
19 changed files with 175 additions and 47 deletions

View File

@@ -1304,6 +1304,24 @@ bool DocumentObject::adjustRelativeLinks(
return touched;
}
std::string DocumentObject::getElementMapVersion(const App::Property* _prop, bool restored) const
{
auto prop = Base::freecad_dynamic_cast<const PropertyComplexGeoData>(_prop);
if (!prop) {
return std::string();
}
return prop->getElementMapVersion(restored);
}
bool DocumentObject::checkElementMapVersion(const App::Property* _prop, const char* ver) const
{
auto prop = Base::freecad_dynamic_cast<const PropertyComplexGeoData>(_prop);
if (!prop) {
return false;
}
return prop->checkElementMapVersion(ver);
}
const std::string &DocumentObject::hiddenMarker() {
static std::string marker("!hide");
return marker;

View File

@@ -300,6 +300,20 @@ public:
bool testIfLinkDAGCompatible(App::PropertyLinkSubList &linksTo) const;
bool testIfLinkDAGCompatible(App::PropertyLinkSub &linkTo) const;
/** Return the element map version of the geometry data stored in the given property
*
* @param prop: the geometry property to query for element map version
* @param restored: whether to query for the restored element map version.
* In case of version upgrade, the restored version may
* be different from the current version.
*
* @return Return the element map version string.
*/
virtual std::string getElementMapVersion(const App::Property *prop, bool restored=false) const;
/// Return true to signal re-generation of geometry element names
virtual bool checkElementMapVersion(const App::Property *prop, const char *ver) const;
public:
/** mustExecute
* We call this method to check if the object was modified to

View File

@@ -225,6 +225,13 @@ Return tuple(obj,newElementName,oldElementName)
<UserDocu>adjustRelativeLinks(parent,recursive=True) -- auto correct potential cyclic dependencies</UserDocu>
</Documentation>
</Methode>
<Methode Name="getElementMapVersion" Const="true">
<Documentation>
<UserDocu>
getElementMapVersion(property_name): return element map version of a given geometry property
</UserDocu>
</Documentation>
</Methode>
<Attribute Name="OutList" ReadOnly="true">
<Documentation>
<UserDocu>A list of all objects this object links to.</UserDocu>

View File

@@ -745,6 +745,22 @@ PyObject* DocumentObjectPy::getPathsByOutList(PyObject *args)
}
}
PyObject* DocumentObjectPy::getElementMapVersion(PyObject* args)
{
const char* name;
PyObject* restored = Py_False;
if (!PyArg_ParseTuple(args, "s|O", &name, &restored)) {
return NULL;
}
Property* prop = getDocumentObjectPtr()->getPropertyByName(name);
if (!prop) {
throw Py::ValueError("property not found");
}
return Py::new_reference_to(
Py::String(getDocumentObjectPtr()->getElementMapVersion(prop, Base::asBoolean(restored))));
}
PyObject *DocumentObjectPy::getCustomAttributes(const char* ) const
{
return nullptr;

View File

@@ -726,8 +726,8 @@ MappedName ElementMap::dehashElementName(const MappedName& name) const
FC_LOG("cannot de-hash id " << id);// NOLINT
return name;
}
MappedName ret(
sid.toString());// FIXME .toString() was missing in original function. is this correct?
MappedName ret(sid);
// sid.toString());// FIXME .toString() was missing in original function. is this correct?
FC_TRACE("de-hash " << name << " -> " << ret);// NOLINT
return ret;
}

View File

@@ -58,6 +58,12 @@ If an object has no such property then None is returned.
Unlike to getPropertyNameOfGeometry this function returns the geometry, not its name.</UserDocu>
</Documentation>
</Methode>
<Attribute Name="ElementMapVersion" ReadOnly="true">
<Documentation>
<UserDocu>Element map version</UserDocu>
</Documentation>
<Parameter Name="ElementMapVersion" Type="String" />
</Attribute>
<CustomAttributes />
</PythonExport>
</GenerateModel>

View File

@@ -93,3 +93,8 @@ int GeoFeaturePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}
Py::String GeoFeaturePy::getElementMapVersion() const {
return Py::String(getGeoFeaturePtr()->getElementMapVersion(
getGeoFeaturePtr()->getPropertyOfGeometry()));
}

View File

@@ -484,7 +484,8 @@ void ExtrusionHelper::createTaperedPrismOffset(TopoDS_Wire sourceWire,
void ExtrusionHelper::makeElementDraft(const ExtrusionParameters& params,
const TopoShape& _shape,
std::vector<TopoShape>& drafts)
std::vector<TopoShape>& drafts,
App::StringHasherRef hasher)
{
double distanceFwd = tan(params.taperAngleFwd) * params.lengthFwd;
double distanceRev = tan(params.taperAngleRev) * params.lengthRev;
@@ -518,7 +519,7 @@ void ExtrusionHelper::makeElementDraft(const ExtrusionParameters& params,
}
else {
unsigned pos = drafts.size();
makeElementDraft(params, outerWire, drafts);
makeElementDraft(params, outerWire, drafts, hasher);
if (drafts.size() != pos + 1) {
Standard_Failure::Raise("Failed to make drafted extrusion");
}
@@ -528,7 +529,7 @@ void ExtrusionHelper::makeElementDraft(const ExtrusionParameters& params,
wires,
"",
TopoShape::SingleShapeCompoundCreationPolicy::returnShape);
makeElementDraft(params, innerWires, inner);
makeElementDraft(params, innerWires, inner, hasher);
if (inner.empty()) {
Standard_Failure::Raise("Failed to make drafted extrusion with inner hole");
}
@@ -550,7 +551,7 @@ void ExtrusionHelper::makeElementDraft(const ExtrusionParameters& params,
}
else if (shape.shapeType() == TopAbs_COMPOUND) {
for (auto& s : shape.getSubTopoShapes()) {
makeElementDraft(params, s, drafts);
makeElementDraft(params, s, drafts, hasher);
}
}
else {
@@ -598,7 +599,7 @@ void ExtrusionHelper::makeElementDraft(const ExtrusionParameters& params,
}
mkGenerator.Build();
drafts.push_back(TopoShape(0).makeElementShape(mkGenerator, list_of_sections));
drafts.push_back(TopoShape(0, hasher).makeElementShape(mkGenerator, list_of_sections));
}
catch (Standard_Failure&) {
throw;

View File

@@ -29,6 +29,7 @@
#include <TopoDS_Shape.hxx>
#include <Mod/Part/PartGlobal.h>
#include "TopoShape.h"
namespace Part
@@ -88,8 +89,10 @@ public:
TopoDS_Wire& result);
/** Same as makeDraft() with support of element mapping
*/
static void
makeElementDraft(const ExtrusionParameters& params, const TopoShape&, std::vector<TopoShape>&);
static void makeElementDraft(const ExtrusionParameters& params,
const TopoShape&,
std::vector<TopoShape>&,
App::StringHasherRef hasher);
};
} //namespace Part

View File

@@ -61,9 +61,12 @@ void Part::FaceMaker::addTopoShape(const TopoShape& shape) {
break;
case TopAbs_WIRE:
this->myWires.push_back(TopoDS::Wire(sh));
this->myTopoWires.push_back(shape);
break;
case TopAbs_EDGE:
this->myWires.push_back(BRepBuilderAPI_MakeWire(TopoDS::Edge(sh)).Wire());
this->myTopoWires.push_back(shape);
this->myTopoWires.back().setShape(this->myWires.back(), false);
break;
case TopAbs_FACE:
this->myInputFaces.push_back(sh);
@@ -186,6 +189,7 @@ void Part::FaceMaker::postBuild() {
if(!op)
op = Part::OpCodes::Face;
const auto &faces = this->myTopoShape.getSubTopoShapes(TopAbs_FACE);
std::set<Data::MappedName> namesUsed;
// name the face using the edges of its outer wire
for(auto &face : faces) {
++index;
@@ -208,10 +212,25 @@ void Part::FaceMaker::postBuild() {
std::vector<Data::MappedName> names;
Data::ElementIDRefs sids;
#ifdef FC_USE_TNP_FIX
// To avoid name collision, we keep track of any used names to make sure
// to use at least 'minElementNames' number of unused element names to
// generate the face name.
int nameCount = 0;
for (const auto &e : edgeNames) {
names.push_back(e.name);
sids += e.sids;
if (namesUsed.insert(e.name).second) {
if (++nameCount >= minElementNames)
break;
}
}
#else
// We just use the first source element name to make the face name more
// stable
names.push_back(edgeNames.begin()->name);
sids = edgeNames.begin()->sids;
#endif
this->myTopoShape.setElementComboName(
Data::IndexedName::fromConst("Face",index),names,op,nullptr,&sids);
}

View File

@@ -107,10 +107,12 @@ public:
protected:
std::vector<TopoShape> mySourceShapes; //wire or compound
std::vector<TopoDS_Wire> myWires; //wires from mySourceShapes
std::vector<TopoShape> myTopoWires;
std::vector<TopoDS_Compound> myCompounds; //compounds, for recursive processing
std::vector<TopoDS_Shape> myShapesToReturn;
std::vector<TopoDS_Shape> myInputFaces;
TopoShape myTopoShape;
int minElementNames = 1;
/**
* @brief Build_Essence: build routine that can assume there is no nesting.

View File

@@ -320,7 +320,7 @@ void Extrusion::extrudeShape(TopoShape &result, const TopoShape &source, const E
Base::SignalException se;
#endif
std::vector<TopoShape> drafts;
ExtrusionHelper::makeElementDraft(params, myShape, drafts);
ExtrusionHelper::makeElementDraft(params, myShape, drafts, result.Hasher);
if (drafts.empty()) {
Standard_Failure::Raise("Drafting shape failed");
}

View File

@@ -28,6 +28,7 @@
#include <App/Link.h>
#include "FeatureOffset.h"
#include <App/Document.h>
using namespace Part;
@@ -96,7 +97,7 @@ App::DocumentObjectExecReturn *Offset::execute()
if(shape.isNull())
return new App::DocumentObjectExecReturn("Invalid source link");
auto join = static_cast<JoinType>(Join.getValue());
this->Shape.setValue(TopoShape(0).makeElementOffset(
this->Shape.setValue(TopoShape(0, getDocument()->getStringHasher()).makeElementOffset(
shape,offset,tol,inter,self,mode,join,fill ? FillType::fill : FillType::noFill));
#endif
return App::DocumentObject::StdReturn;

View File

@@ -45,6 +45,7 @@
#include <App/Link.h>
#include <App/Document.h>
#include "PartFeatures.h"
#include "TopoShapeOpCode.h"
@@ -837,7 +838,7 @@ App::DocumentObjectExecReturn* Thickness::execute()
short join = (short)Join.getValue();
#ifdef FC_USE_TNP_FIX
this->Shape.setValue(TopoShape(0)
this->Shape.setValue(TopoShape(0,getDocument()->getStringHasher())
.makeElementThickSolid(base,
shapes,
thickness,

View File

@@ -1435,7 +1435,6 @@ TopoShape& TopoShape::makeShapeWithElementMap(const TopoDS_Shape& shape,
if (otherMap.count() == 0) {
continue;
}
for (int i = 1; i <= otherMap.count(); i++) {
const auto& otherElement = otherMap.find(incomingShape._Shape, i);
// Find all new objects that are a modification of the old object
@@ -1754,7 +1753,6 @@ TopoShape& TopoShape::makeShapeWithElementMap(const TopoDS_Shape& shape,
elementMap()
->encodeElementName(element[0], first_name, ss, &sids, Tag, op, first_key.tag);
elementMap()->setElementName(element, first_name, Tag, &sids);
if (!delayed && first_key.shapetype < 3) {
newNames.erase(itName);
}
@@ -1852,7 +1850,7 @@ TopoShape& TopoShape::makeShapeWithElementMap(const TopoDS_Shape& shape,
elementMap()->encodeElementName(indexedName[0], newName, ss, &sids, Tag, op);
elementMap()->setElementName(indexedName, newName, Tag, &sids);
}
}
}
}

View File

@@ -122,7 +122,11 @@ static Py_hash_t _TopoShapeHash(PyObject* self)
"This reference is no longer valid!");
return 0;
}
#if OCC_VERSION_HEX >= 0x070800
return std::hash<TopoDS_Shape> {}(static_cast<TopoShapePy*>(self)->getTopoShapePtr()->getShape());
#else
return static_cast<TopoShapePy*>(self)->getTopoShapePtr()->getShape().HashCode(INT_MAX);
#endif
}
struct TopoShapePyInit

View File

@@ -555,7 +555,7 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
}
sketchshape.move(invObjLoc);
TopoShape prism(0);
TopoShape prism(0, getDocument()->getStringHasher());
if (method == "UpToFirst" || method == "UpToLast" || method == "UpToFace") {
// Note: This will return an unlimited planar face if support is a datum plane
@@ -663,7 +663,7 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
params.dir.Reverse();
}
std::vector<TopoShape> drafts;
Part::ExtrusionHelper::makeElementDraft(params, sketchshape, drafts);
Part::ExtrusionHelper::makeElementDraft(params, sketchshape, drafts, getDocument()->getStringHasher());
if (drafts.empty()) {
return new App::DocumentObjectExecReturn(
QT_TRANSLATE_NOOP("Exception", "Padding with draft angle failed"));
@@ -693,7 +693,7 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
prism.Tag = -this->getID();
// Let's call algorithm computing a fuse operation:
TopoShape result(0);
TopoShape result(0, getDocument()->getStringHasher());
try {
const char* maker;
switch (getAddSubType()) {

View File

@@ -110,11 +110,38 @@ class TestTopologicalNamingProblem(unittest.TestCase):
else:
print("TOPOLOGICAL NAMING PROBLEM IS PRESENT.")
def testPartDesignElementMapPad(self):
""" Test that padding a sketch results in a correct element map. Note that comprehensive testing
of the geometric functionality of the Pad is in TestPad.py """
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
padSketch = self.Doc.addObject('Sketcher::SketchObject', 'SketchPad')
pad = self.Doc.addObject("PartDesign::Pad", "Pad")
body.addObject(padSketch)
body.addObject(pad)
TestSketcherApp.CreateRectangleSketch(padSketch, (0, 0), (1, 1))
pad.Profile = padSketch
pad.Length = 1
# Act
self.Doc.recompute()
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
reverseMap = pad.Shape.ElementReverseMap
faces = [name for name in reverseMap.keys() if name.startswith("Face")]
edges = [name for name in reverseMap.keys() if name.startswith("Edge")]
vertexes = [name for name in reverseMap.keys() if name.startswith("Vertex")]
# Assert
self.assertEqual(pad.Shape.ElementMapSize,30) # 4 duplicated Vertexes in here
self.assertEqual(len(reverseMap),26)
self.assertEqual(len(faces),6)
self.assertEqual(len(edges),12)
self.assertEqual(len(vertexes),8)
def testPartDesignElementMapBox(self):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
box = self.Doc.addObject('PartDesign::AdditiveBox', 'Box')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(box.Shape.childShapes()), 0)
@@ -131,7 +158,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
cylinder = self.Doc.addObject('PartDesign::AdditiveCylinder', 'Cylinder')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(cylinder.Shape.childShapes()), 0)
@@ -148,7 +175,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
sphere = self.Doc.addObject('PartDesign::AdditiveSphere', 'Sphere')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(sphere.Shape.childShapes()), 0)
@@ -165,7 +192,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
cone = self.Doc.addObject('PartDesign::AdditiveCone', 'Cone')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(cone.Shape.childShapes()), 0)
@@ -182,7 +209,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
ellipsoid = self.Doc.addObject('PartDesign::AdditiveEllipsoid', 'Ellipsoid')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(ellipsoid.Shape.childShapes()), 0)
@@ -199,7 +226,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
torus = self.Doc.addObject('PartDesign::AdditiveTorus', 'Torus')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(torus.Shape.childShapes()), 0)
@@ -216,7 +243,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
prism = self.Doc.addObject('PartDesign::AdditivePrism', 'Prism')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(prism.Shape.childShapes()), 0)
@@ -233,7 +260,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
# Arrange
body = self.Doc.addObject('PartDesign::Body', 'Body')
wedge = self.Doc.addObject('PartDesign::AdditiveWedge', 'Wedge')
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act / Assert
self.assertEqual(len(wedge.Shape.childShapes()), 0)
@@ -256,7 +283,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subbox = self.Doc.addObject('PartDesign::SubtractiveBox', 'Box')
@@ -275,7 +302,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subcylinder = self.Doc.addObject('PartDesign::SubtractiveCylinder', 'Cylinder')
@@ -294,7 +321,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subsphere = self.Doc.addObject('PartDesign::SubtractiveSphere', 'Sphere')
@@ -313,7 +340,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subcone = self.Doc.addObject('PartDesign::SubtractiveCone', 'Cone')
@@ -332,7 +359,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subellipsoid = self.Doc.addObject('PartDesign::SubtractiveEllipsoid', 'Ellipsoid')
@@ -351,7 +378,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subtorus = self.Doc.addObject('PartDesign::SubtractiveTorus', 'Torus')
@@ -370,7 +397,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subprism = self.Doc.addObject('PartDesign::SubtractivePrism', 'Prism')
@@ -389,7 +416,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
box.Width = 20
box.Height = 20
body.addObject(box)
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
subwedge = self.Doc.addObject('PartDesign::SubtractiveWedge', 'Wedge')
@@ -405,22 +432,27 @@ class TestTopologicalNamingProblem(unittest.TestCase):
body = self.Doc.addObject('PartDesign::Body', 'Body')
sketch = self.Doc.addObject('Sketcher::SketchObject', 'Sketch')
TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1))
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
pad = self.Doc.addObject('PartDesign::Pad', 'Pad')
pad.Profile = sketch
pad.BaseFeature = sketch
body.addObject(sketch)
body.addObject(pad)
self.Doc.recompute()
# Assert
self.assertEqual(len(body.Shape.childShapes()), 1)
self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26)
# self.assertEqual(len(body.Shape.childShapes()), 1)
if App.GuiUp:
# Todo: This triggers a 'hasher mismatch' warning in TopoShape::mapSubElement as called by
# flushElementMap. This appears to be the case whenever you have a parent with a hasher
# that has children without hashmaps. The warning seems to be spurious in this case, but
# perhaps there is a solution involving setting hashmaps on all elements.
self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 30)
else:
self.assertEqual(body.Shape.childShapes()[0].ElementMapSize, 26)
self.assertEqual(body.Shape.ElementMapSize,30)
self.assertEqual(sketch.Shape.ElementMapSize,12)
self.assertEqual(pad.Shape.ElementMapSize,30)
self.assertEqual(pad.Shape.childShapes()[0].ElementMapSize,30)
# Todo: Assert that the names in the ElementMap are good; in particular that they are hashed with a # starting
def testPartDesignElementMapRevolution(self):
@@ -428,7 +460,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
body = self.Doc.addObject('PartDesign::Body', 'Body')
sketch = self.Doc.addObject('Sketcher::SketchObject', 'Sketch')
TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1))
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
revolution = self.Doc.addObject('PartDesign::Revolution', 'Revolution')
@@ -449,7 +481,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
sketch2 = self.Doc.addObject('Sketcher::SketchObject', 'Sketch')
TestSketcherApp.CreateRectangleSketch(sketch2, (0, 0), (2, 2))
sketch2.Placement.move(App.Vector(0, 0, 3))
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
loft = self.Doc.addObject('PartDesign::AdditiveLoft', 'Loft')
@@ -470,7 +502,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1))
sketch2 = self.Doc.addObject('Sketcher::SketchObject', 'Sketch')
TestSketcherApp.CreateRectangleSketch(sketch2, (0, 0), (2, 2))
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
pipe = self.Doc.addObject('PartDesign::AdditivePipe', 'Pipe')
@@ -489,7 +521,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
body = self.Doc.addObject('PartDesign::Body', 'Body')
sketch = self.Doc.addObject('Sketcher::SketchObject', 'Sketch')
TestSketcherApp.CreateRectangleSketch(sketch, (0, 0), (1, 1))
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Act
helix = self.Doc.addObject('PartDesign::AdditiveHelix', 'Helix')
@@ -524,6 +556,8 @@ class TestTopologicalNamingProblem(unittest.TestCase):
groove.Reversed = 0
groove.Base = App.Vector(0, 0, 0)
self.Doc.recompute()
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Assert
# print(groove.Shape.childShapes()[0].ElementMap)
# TODO: Complete me as part of the subtractive features
@@ -548,14 +582,13 @@ class TestTopologicalNamingProblem(unittest.TestCase):
pad.Profile = sketch
body.addObject(pad)
self.Doc.recompute()
if not hasattr(body,"ElementMapVersion"): # Skip without element maps.
if body.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Assert
self.assertEqual(sketch.Shape.ElementMapSize, 12)
self.assertEqual(pad.Shape.ElementMapSize, 30) # The sketch plus the pad in the map
# TODO: differing results between main and LS3 on these values. Does it matter?
# self.assertEqual(body.Shape.ElementMapSize,0) # 8?
# self.Doc.recompute()
# self.assertEqual(body.Shape.ElementMapSize,30) # 26
def testPlaneElementMap(self):
@@ -567,7 +600,7 @@ class TestTopologicalNamingProblem(unittest.TestCase):
pad = self.Doc.addObject('PartDesign::Pad', 'Pad')
pad.Profile = plane
self.Doc.recompute()
if not hasattr(pad,"ElementMapVersion"): # Skip without element maps.
if pad.Shape.ElementMapVersion == "": # Should be '4' as of Mar 2023.
return
# Assert
self.assertEqual(plane.Shape.ElementMapSize, 0)

View File

@@ -299,7 +299,7 @@ void SketchObject::buildShape()
Shape.setValue(Part::TopoShape());
return;
}
Part::TopoShape result(0);
Part::TopoShape result(0, getDocument()->getStringHasher());
if (vertices.empty()) {
// Notice here we supply op code Part::OpCodes::Sketch to makEWires().
result.makeElementWires(shapes,Part::OpCodes::Sketch);