Merge pull request #12943 from bgbsww/bgbsww-toponamingFeatureChamfer
Toponaming/part features chamfer, fillet; dependencies and test updates
This commit is contained in:
@@ -52,7 +52,7 @@ using BoundBox3d = BoundBox3<double>;
|
||||
namespace Data
|
||||
{
|
||||
|
||||
struct MappedChildElements;
|
||||
//struct MappedChildElements;
|
||||
|
||||
/** Segments
|
||||
* Sub-element type of the ComplexGeoData type
|
||||
|
||||
@@ -129,12 +129,16 @@ public:
|
||||
/// include the index.
|
||||
///
|
||||
/// \param buffer A (possibly non-empty) string buffer to append the name to.
|
||||
void appendToStringBuffer(std::string & buffer) const
|
||||
/// \return A const char pointer to the name we appended to the buffer.
|
||||
const char * appendToStringBuffer(std::string & buffer) const
|
||||
{
|
||||
// Note! buffer is not cleared on purpose.
|
||||
std::size_t offset = buffer.size();
|
||||
buffer += this->type;
|
||||
if (this->index > 0) {
|
||||
buffer += std::to_string(this->index);
|
||||
}
|
||||
return buffer.c_str() + offset;
|
||||
}
|
||||
|
||||
/// Create and return a new std::string with this name in it.
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include "FeatureChamfer.h"
|
||||
#include "TopoShapeOpCode.h"
|
||||
|
||||
|
||||
using namespace Part;
|
||||
@@ -47,12 +48,14 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
return new App::DocumentObjectExecReturn("No object linked");
|
||||
|
||||
try {
|
||||
TopoShape baseTopoShape = Feature::getTopoShape(link);
|
||||
auto baseShape = Feature::getShape(link);
|
||||
BRepFilletAPI_MakeChamfer mkChamfer(baseShape);
|
||||
TopTools_IndexedMapOfShape mapOfEdges;
|
||||
TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
|
||||
TopExp::MapShapesAndAncestors(baseShape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
|
||||
TopTools_IndexedMapOfShape mapOfEdges;
|
||||
TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfEdges);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
|
||||
std::vector<FilletElement> values = Edges.getValues();
|
||||
for (const auto & value : values) {
|
||||
@@ -89,6 +92,39 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
prop.touch();
|
||||
|
||||
return App::DocumentObject::StdReturn;
|
||||
#else
|
||||
const auto &vals = EdgeLinks.getSubValues();
|
||||
const auto &subs = EdgeLinks.getShadowSubs();
|
||||
if(subs.size()!=(size_t)Edges.getSize())
|
||||
return new App::DocumentObjectExecReturn("Edge link size mismatch");
|
||||
size_t i=0;
|
||||
for(const auto &info : Edges.getValues()) {
|
||||
auto &sub = subs[i];
|
||||
auto &ref = sub.first.size()?sub.first:vals[i];
|
||||
++i;
|
||||
// Toponaming project March 2024: Replaced this code because it wouldn't work:
|
||||
// TopoDS_Shape edge;
|
||||
// try {
|
||||
// edge = baseTopoShape.getSubShape(ref.c_str());
|
||||
// }catch(...){}
|
||||
auto id = Data::MappedName(ref.c_str()).toIndexedName().getIndex();
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(mapOfEdges.FindKey(id));
|
||||
if(edge.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Invalid edge link");
|
||||
double radius1 = info.radius1;
|
||||
double radius2 = info.radius2;
|
||||
const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First());
|
||||
mkChamfer.Add(radius1, radius2, TopoDS::Edge(edge), face);
|
||||
}
|
||||
|
||||
TopoDS_Shape shape = mkChamfer.Shape();
|
||||
if (shape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is null");
|
||||
|
||||
TopoShape res(0);
|
||||
this->Shape.setValue(res.makeElementShape(mkChamfer,baseTopoShape,Part::OpCodes::Chamfer));
|
||||
return Part::Feature::execute();
|
||||
#endif
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include "FeatureFillet.h"
|
||||
#include "TopoShapeOpCode.h"
|
||||
|
||||
|
||||
using namespace Part;
|
||||
@@ -48,15 +49,19 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
if (!link)
|
||||
return new App::DocumentObjectExecReturn("No object linked");
|
||||
|
||||
auto baseShape = Feature::getShape(link);
|
||||
|
||||
try {
|
||||
#if defined(__GNUC__) && defined (FC_OS_LINUX)
|
||||
Base::SignalException se;
|
||||
#endif
|
||||
auto baseShape = Feature::getShape(link);
|
||||
TopoShape baseTopoShape = Feature::getTopoShape(link);
|
||||
BRepFilletAPI_MakeFillet mkFillet(baseShape);
|
||||
TopTools_IndexedMapOfShape mapOfShape;
|
||||
TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfShape);
|
||||
TopTools_IndexedMapOfShape mapOfEdges;
|
||||
TopExp::MapShapes(baseShape, TopAbs_EDGE, mapOfEdges);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
|
||||
std::vector<FilletElement> values = Edges.getValues();
|
||||
for (const auto & value : values) {
|
||||
@@ -92,6 +97,38 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
prop.touch();
|
||||
|
||||
return App::DocumentObject::StdReturn;
|
||||
#else
|
||||
const auto &vals = EdgeLinks.getSubValues();
|
||||
const auto &subs = EdgeLinks.getShadowSubs();
|
||||
if(subs.size()!=(size_t)Edges.getSize())
|
||||
return new App::DocumentObjectExecReturn("Edge link size mismatch");
|
||||
size_t i=0;
|
||||
for(const auto &info : Edges.getValues()) {
|
||||
auto &sub = subs[i];
|
||||
auto &ref = sub.first.size()?sub.first:vals[i];
|
||||
++i;
|
||||
// Toponaming project March 2024: Replaced this code because it wouldn't work:
|
||||
// TopoDS_Shape edge;
|
||||
// try {
|
||||
// edge = baseTopoShape.getSubShape(ref.c_str());
|
||||
// }catch(...){}
|
||||
auto id = Data::MappedName(ref.c_str()).toIndexedName().getIndex();
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(mapOfEdges.FindKey(id));
|
||||
if(edge.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Invalid edge link");
|
||||
double radius1 = info.radius1;
|
||||
double radius2 = info.radius2;
|
||||
mkFillet.Add(radius1, radius2, TopoDS::Edge(edge));
|
||||
}
|
||||
|
||||
TopoDS_Shape shape = mkFillet.Shape();
|
||||
if (shape.IsNull())
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is null");
|
||||
|
||||
TopoShape res(0);
|
||||
this->Shape.setValue(res.makeElementShape(mkFillet,baseTopoShape,Part::OpCodes::Fillet));
|
||||
return Part::Feature::execute();
|
||||
#endif
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
return new App::DocumentObjectExecReturn(e.GetMessageString());
|
||||
|
||||
@@ -1217,16 +1217,69 @@ FilletBase::FilletBase()
|
||||
{
|
||||
ADD_PROPERTY(Base,(nullptr));
|
||||
ADD_PROPERTY(Edges,(0,0,0));
|
||||
ADD_PROPERTY_TYPE(EdgeLinks,(0), 0,
|
||||
(App::PropertyType)(App::Prop_ReadOnly|App::Prop_Hidden),0);
|
||||
Edges.setSize(0);
|
||||
}
|
||||
|
||||
short FilletBase::mustExecute() const
|
||||
{
|
||||
if (Base.isTouched() || Edges.isTouched())
|
||||
if (Base.isTouched() || Edges.isTouched() || EdgeLinks.isTouched())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FilletBase::onChanged(const App::Property *prop) {
|
||||
if(getDocument() && !getDocument()->testStatus(App::Document::Restoring)) {
|
||||
if(prop == &Edges || prop == &Base) {
|
||||
if(!prop->testStatus(App::Property::User3))
|
||||
syncEdgeLink();
|
||||
}
|
||||
}
|
||||
Feature::onChanged(prop);
|
||||
}
|
||||
|
||||
void FilletBase::onDocumentRestored() {
|
||||
if(EdgeLinks.getSubValues().empty())
|
||||
syncEdgeLink();
|
||||
Feature::onDocumentRestored();
|
||||
}
|
||||
|
||||
void FilletBase::syncEdgeLink() {
|
||||
if(!Base.getValue() || !Edges.getSize()) {
|
||||
EdgeLinks.setValue(0);
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> subs;
|
||||
std::string sub("Edge");
|
||||
for(auto &info : Edges.getValues())
|
||||
subs.emplace_back(sub+std::to_string(info.edgeid));
|
||||
EdgeLinks.setValue(Base.getValue(),subs);
|
||||
}
|
||||
|
||||
void FilletBase::onUpdateElementReference(const App::Property *prop) {
|
||||
if(prop!=&EdgeLinks || !getNameInDocument())
|
||||
return;
|
||||
auto values = Edges.getValues();
|
||||
const auto &subs = EdgeLinks.getSubValues();
|
||||
for(size_t i=0;i<values.size();++i) {
|
||||
if(i>=subs.size()) {
|
||||
FC_WARN("fillet edge count mismatch in object " << getFullName());
|
||||
break;
|
||||
}
|
||||
int idx = 0;
|
||||
sscanf(subs[i].c_str(),"Edge%d",&idx);
|
||||
if(idx)
|
||||
values[i].edgeid = idx;
|
||||
else
|
||||
FC_WARN("invalid fillet edge link '" << subs[i] << "' in object "
|
||||
<< getFullName());
|
||||
}
|
||||
Edges.setStatus(App::Property::User3,true);
|
||||
Edges.setValues(values);
|
||||
Edges.setStatus(App::Property::User3,false);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
PROPERTY_SOURCE(Part::FeatureExt, Part::Feature)
|
||||
|
||||
@@ -175,8 +175,15 @@ public:
|
||||
|
||||
App::PropertyLink Base;
|
||||
PropertyFilletEdges Edges;
|
||||
App::PropertyLinkSub EdgeLinks;
|
||||
|
||||
short mustExecute() const override;
|
||||
void onUpdateElementReference(const App::Property *prop) override;
|
||||
|
||||
protected:
|
||||
void onDocumentRestored() override;
|
||||
void onChanged(const App::Property *) override;
|
||||
void syncEdgeLink();
|
||||
};
|
||||
|
||||
using FeaturePython = App::FeaturePythonT<Feature>;
|
||||
|
||||
@@ -336,6 +336,7 @@ Data::Segment* TopoShape::getSubElement(const char* Type, unsigned long n) const
|
||||
return new ShapeSegment(getSubShape(temp.c_str()));
|
||||
}
|
||||
|
||||
// Type can be (should be?) a subshape name, not a type, E.G. Edge3
|
||||
TopoDS_Shape TopoShape::getSubShape(const char* Type, bool silent) const {
|
||||
TopoShape s(*this);
|
||||
s.Tag = 0;
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
#include "Geometry.h"
|
||||
#include "BRepOffsetAPI_MakeOffsetFix.h"
|
||||
|
||||
#include <App/ElementMap.h>
|
||||
#include <App/ElementNamingUtils.h>
|
||||
#include <ShapeAnalysis_FreeBoundsProperties.hxx>
|
||||
#include <BRepBuilderAPI_MakeSolid.hxx>
|
||||
@@ -271,7 +272,7 @@ TopoDS_Shape TopoShape::located(const TopoDS_Shape& tds, const gp_Trsf& transfer
|
||||
return moved(sCopy, transfer);
|
||||
}
|
||||
|
||||
void TopoShape::operator = (const TopoShape& sh)
|
||||
void TopoShape::operator=(const TopoShape& sh)
|
||||
{
|
||||
if (this != &sh) {
|
||||
this->setShape(sh._Shape, true);
|
||||
@@ -814,6 +815,7 @@ void TopoShape::mapSubElementForShape(const TopoShape& other, const char* op)
|
||||
|
||||
void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool forceHasher)
|
||||
{
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
if (!canMapElement(other)) {
|
||||
return;
|
||||
}
|
||||
@@ -831,6 +833,115 @@ void TopoShape::mapSubElement(const TopoShape& other, const char* op, bool force
|
||||
}
|
||||
|
||||
mapSubElementForShape(other, op);
|
||||
#else
|
||||
if (!canMapElement(other)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getElementMapSize(false) && this->_Shape.IsPartner(other._Shape)) {
|
||||
if (!this->Hasher) {
|
||||
this->Hasher = other.Hasher;
|
||||
}
|
||||
copyElementMap(other, op);
|
||||
return;
|
||||
}
|
||||
|
||||
bool warned = false;
|
||||
static const std::array<TopAbs_ShapeEnum, 3> types = {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE};
|
||||
|
||||
auto checkHasher = [this](const TopoShape& other) {
|
||||
if (Hasher) {
|
||||
if (other.Hasher != Hasher) {
|
||||
if (!getElementMapSize(false)) {
|
||||
if (FC_LOG_INSTANCE.isEnabled(FC_LOGLEVEL_LOG)) {
|
||||
FC_WARN("hasher mismatch");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// FC_THROWM(Base::RuntimeError, "hasher mismatch");
|
||||
FC_ERR("hasher mismatch");
|
||||
}
|
||||
Hasher = other.Hasher;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Hasher = other.Hasher;
|
||||
}
|
||||
};
|
||||
|
||||
for (auto type : types) {
|
||||
auto& shapeMap = _cache->getAncestry(type);
|
||||
auto& otherMap = other._cache->getAncestry(type);
|
||||
if (!shapeMap.count() || !otherMap.count()) {
|
||||
continue;
|
||||
}
|
||||
if (!forceHasher && other.Hasher) {
|
||||
forceHasher = true;
|
||||
checkHasher(other);
|
||||
}
|
||||
const char* shapetype = shapeName(type).c_str();
|
||||
std::ostringstream ss;
|
||||
|
||||
bool forward;
|
||||
int count;
|
||||
if (otherMap.count() <= shapeMap.count()) {
|
||||
forward = true;
|
||||
count = otherMap.count();
|
||||
}
|
||||
else {
|
||||
forward = false;
|
||||
count = shapeMap.count();
|
||||
}
|
||||
for (int k = 1; k <= count; ++k) {
|
||||
int i, idx;
|
||||
if (forward) {
|
||||
i = k;
|
||||
idx = shapeMap.find(_Shape, otherMap.find(other._Shape, k));
|
||||
if (!idx) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
idx = k;
|
||||
i = otherMap.find(other._Shape, shapeMap.find(_Shape, k));
|
||||
if (!i) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Data::IndexedName element = Data::IndexedName::fromConst(shapetype, idx);
|
||||
for (auto& v :
|
||||
other.getElementMappedNames(Data::IndexedName::fromConst(shapetype, i), true)) {
|
||||
auto& name = v.first;
|
||||
auto& sids = v.second;
|
||||
if (sids.size()) {
|
||||
if (!Hasher) {
|
||||
Hasher = sids[0].getHasher();
|
||||
}
|
||||
else if (!sids[0].isFromSameHasher(Hasher)) {
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
FC_WARN("hasher mismatch");
|
||||
}
|
||||
sids.clear();
|
||||
}
|
||||
}
|
||||
ss.str("");
|
||||
|
||||
// Originally in ComplexGeoData::setElementName
|
||||
// LinkStable/src/App/ComplexGeoData.cpp#L1631
|
||||
// No longer possible after map separated in ElementMap.cpp
|
||||
|
||||
if (!elementMap()) {
|
||||
resetElementMap(std::make_shared<Data::ElementMap>());
|
||||
}
|
||||
|
||||
elementMap()->encodeElementName(shapetype[0], name, ss, &sids, Tag, op, other.Tag);
|
||||
elementMap()->setElementName(element, name, Tag, &sids);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void TopoShape::mapSubElementsTo(std::vector<TopoShape>& shapes, const char* op) const
|
||||
@@ -892,6 +1003,7 @@ void TopoShape::mapCompoundSubElements(const std::vector<TopoShape>& shapes, con
|
||||
|
||||
void TopoShape::mapSubElement(const std::vector<TopoShape>& shapes, const char* op)
|
||||
{
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
if (shapes.empty()) {
|
||||
return;
|
||||
}
|
||||
@@ -904,6 +1016,59 @@ void TopoShape::mapSubElement(const std::vector<TopoShape>& shapes, const char*
|
||||
mapSubElement(shape, op);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (shapes.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shapeType(true) == TopAbs_COMPOUND) {
|
||||
int count = 0;
|
||||
for (auto& s : shapes) {
|
||||
if (s.isNull()) {
|
||||
continue;
|
||||
}
|
||||
if (!getSubShape(TopAbs_SHAPE, ++count, true).IsPartner(s._Shape)) {
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count) {
|
||||
std::vector<Data::ElementMap::MappedChildElements> children;
|
||||
children.reserve(count * 3);
|
||||
TopAbs_ShapeEnum types[] = {TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE};
|
||||
for (unsigned i = 0; i < sizeof(types) / sizeof(types[0]); ++i) {
|
||||
int offset = 0;
|
||||
for (auto& s : shapes) {
|
||||
if (s.isNull()) {
|
||||
continue;
|
||||
}
|
||||
int count = s.countSubShapes(types[i]);
|
||||
if (!count) {
|
||||
continue;
|
||||
}
|
||||
children.emplace_back();
|
||||
auto& child = children.back();
|
||||
child.indexedName =
|
||||
Data::IndexedName::fromConst(shapeName(types[i]).c_str(), 1);
|
||||
child.offset = offset;
|
||||
offset += count;
|
||||
child.count = count;
|
||||
child.elementMap = s.elementMap();
|
||||
child.tag = s.Tag;
|
||||
if (op) {
|
||||
child.postfix = op;
|
||||
}
|
||||
}
|
||||
}
|
||||
setMappedChildElements(children);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& shape : shapes) {
|
||||
mapSubElement(shape, op);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Shape> TopoShape::getSubShapes(TopAbs_ShapeEnum type,
|
||||
@@ -3361,18 +3526,20 @@ struct MapperThruSections: MapperMaker
|
||||
}
|
||||
};
|
||||
|
||||
struct MapperPrism: MapperMaker {
|
||||
struct MapperPrism: MapperMaker
|
||||
{
|
||||
std::unordered_map<TopoDS_Shape, TopoDS_Shape, ShapeHasher, ShapeHasher> vertexMap;
|
||||
ShapeMapper::ShapeMap edgeMap;
|
||||
|
||||
MapperPrism(BRepFeat_MakePrism &maker, const TopoShape &upTo)
|
||||
:MapperMaker(maker)
|
||||
MapperPrism(BRepFeat_MakePrism& maker, const TopoShape& upTo)
|
||||
: MapperMaker(maker)
|
||||
{
|
||||
(void)upTo;
|
||||
|
||||
std::vector<TopoShape> shapes;
|
||||
for(TopTools_ListIteratorOfListOfShape it(maker.FirstShape());it.More();it.Next())
|
||||
for (TopTools_ListIteratorOfListOfShape it(maker.FirstShape()); it.More(); it.Next()) {
|
||||
shapes.push_back(it.Value());
|
||||
}
|
||||
|
||||
if (shapes.size()) {
|
||||
// It seems that BRepFeat_MakePrism::newEdges() does not return
|
||||
@@ -3382,18 +3549,21 @@ struct MapperPrism: MapperMaker {
|
||||
// i.e. the bottom profile, and add all edges that shares a
|
||||
// vertex with the profiles as new edges.
|
||||
|
||||
std::unordered_set<TopoDS_Shape,ShapeHasher,ShapeHasher> edgeSet;
|
||||
std::unordered_set<TopoDS_Shape, ShapeHasher, ShapeHasher> edgeSet;
|
||||
TopoShape bottom;
|
||||
bottom.makeElementCompound(shapes, nullptr, TopoShape::SingleShapeCompoundCreationPolicy::returnShape);
|
||||
bottom.makeElementCompound(shapes,
|
||||
nullptr,
|
||||
TopoShape::SingleShapeCompoundCreationPolicy::returnShape);
|
||||
TopoShape shape(maker.Shape());
|
||||
for (auto &vertex : bottom.getSubShapes(TopAbs_VERTEX)) {
|
||||
for (auto &e : shape.findAncestorsShapes(vertex, TopAbs_EDGE)) {
|
||||
for (auto& vertex : bottom.getSubShapes(TopAbs_VERTEX)) {
|
||||
for (auto& e : shape.findAncestorsShapes(vertex, TopAbs_EDGE)) {
|
||||
// Make sure to not visit the the same edge twice.
|
||||
// And check only edge that are not found in the bottom profile
|
||||
if (!edgeSet.insert(e).second && !bottom.findShape(e)) {
|
||||
auto otherVertex = TopExp::FirstVertex(TopoDS::Edge(e));
|
||||
if (otherVertex.IsSame(vertex))
|
||||
if (otherVertex.IsSame(vertex)) {
|
||||
otherVertex = TopExp::LastVertex(TopoDS::Edge(e));
|
||||
}
|
||||
vertexMap[vertex] = otherVertex;
|
||||
}
|
||||
}
|
||||
@@ -3405,37 +3575,44 @@ struct MapperPrism: MapperMaker {
|
||||
// corresponding edges in the top profile, what an extra criteria
|
||||
// for disambiguation. That is, the pair of edges (bottom and top)
|
||||
// must belong to the same face.
|
||||
for (auto &edge : bottom.getSubShapes(TopAbs_EDGE)) {
|
||||
for (auto& edge : bottom.getSubShapes(TopAbs_EDGE)) {
|
||||
std::vector<int> indices;
|
||||
auto first = TopExp::FirstVertex(TopoDS::Edge(edge));
|
||||
auto last = TopExp::LastVertex(TopoDS::Edge(edge));
|
||||
auto itFirst = vertexMap.find(first);
|
||||
auto itLast = vertexMap.find(last);
|
||||
if (itFirst == vertexMap.end() || itLast ==vertexMap.end())
|
||||
if (itFirst == vertexMap.end() || itLast == vertexMap.end()) {
|
||||
continue;
|
||||
}
|
||||
std::vector<TopoShape> faces;
|
||||
for (int idx : shape.findAncestors(edge, TopAbs_FACE))
|
||||
for (int idx : shape.findAncestors(edge, TopAbs_FACE)) {
|
||||
faces.push_back(shape.getSubTopoShape(TopAbs_FACE, idx));
|
||||
if (faces.empty())
|
||||
}
|
||||
if (faces.empty()) {
|
||||
continue;
|
||||
}
|
||||
for (int idx : shape.findAncestors(itFirst->second, TopAbs_EDGE)) {
|
||||
auto e = shape.getSubTopoShape(TopAbs_EDGE, idx);
|
||||
if (!e.findShape(itLast->second))
|
||||
if (!e.findShape(itLast->second)) {
|
||||
continue;
|
||||
for (auto &face : faces) {
|
||||
if (!face.findShape(e.getShape()))
|
||||
}
|
||||
for (auto& face : faces) {
|
||||
if (!face.findShape(e.getShape())) {
|
||||
continue;
|
||||
auto &entry = edgeMap[edge];
|
||||
if (entry.shapeSet.insert(e.getShape()).second)
|
||||
}
|
||||
auto& entry = edgeMap[edge];
|
||||
if (entry.shapeSet.insert(e.getShape()).second) {
|
||||
entry.shapes.push_back(e.getShape());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual const std::vector<TopoDS_Shape> &generated(const TopoDS_Shape &s) const override {
|
||||
virtual const std::vector<TopoDS_Shape>& generated(const TopoDS_Shape& s) const override
|
||||
{
|
||||
_res.clear();
|
||||
switch(s.ShapeType()) {
|
||||
switch (s.ShapeType()) {
|
||||
case TopAbs_VERTEX: {
|
||||
auto it = vertexMap.find(s);
|
||||
if (it != vertexMap.end()) {
|
||||
@@ -3446,9 +3623,10 @@ struct MapperPrism: MapperMaker {
|
||||
}
|
||||
case TopAbs_EDGE: {
|
||||
auto it = edgeMap.find(s);
|
||||
if (it != edgeMap.end())
|
||||
return it->second.shapes;
|
||||
break;
|
||||
if (it != edgeMap.end()) {
|
||||
return it->second.shapes;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@@ -3651,7 +3829,7 @@ TopoShape& TopoShape::makeElementFilledFace(const std::vector<TopoShape>& _shape
|
||||
// TODO: This method does not appear to ever be called in the codebase, and it is probably
|
||||
// broken, because using TopoShape() with no parameters means the result will not have an
|
||||
// element Map.
|
||||
//TopoShape& TopoShape::makeElementSolid(const std::vector<TopoShape>& shapes, const char* op)
|
||||
// TopoShape& TopoShape::makeElementSolid(const std::vector<TopoShape>& shapes, const char* op)
|
||||
//{
|
||||
// return makeElementSolid(TopoShape().makeElementCompound(shapes), op);
|
||||
//}
|
||||
@@ -3951,22 +4129,25 @@ TopoShape& TopoShape::makeElementShape(BRepBuilderAPI_MakeShape& mkShape,
|
||||
{
|
||||
TopoDS_Shape shape;
|
||||
// OCCT 7.3.x requires calling Solid() and not Shape() to function correctly
|
||||
if ( typeid(mkShape) == typeid(BRepPrimAPI_MakeHalfSpace) ) {
|
||||
if (typeid(mkShape) == typeid(BRepPrimAPI_MakeHalfSpace)) {
|
||||
shape = static_cast<BRepPrimAPI_MakeHalfSpace&>(mkShape).Solid();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
shape = mkShape.Shape();
|
||||
}
|
||||
return makeShapeWithElementMap(shape, MapperMaker(mkShape), shapes, op);
|
||||
}
|
||||
|
||||
TopoShape &TopoShape::makeElementShape(BRepFeat_MakePrism &mkShape,
|
||||
const std::vector<TopoShape> &sources,
|
||||
const TopoShape &upTo,
|
||||
const char *op)
|
||||
TopoShape& TopoShape::makeElementShape(BRepFeat_MakePrism& mkShape,
|
||||
const std::vector<TopoShape>& sources,
|
||||
const TopoShape& upTo,
|
||||
const char* op)
|
||||
{
|
||||
if(!op) op = Part::OpCodes::Prism;
|
||||
if (!op) {
|
||||
op = Part::OpCodes::Prism;
|
||||
}
|
||||
MapperPrism mapper(mkShape, upTo);
|
||||
makeShapeWithElementMap(mkShape.Shape(),mapper,sources,op);
|
||||
makeShapeWithElementMap(mkShape.Shape(), mapper, sources, op);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -4052,7 +4233,7 @@ TopoShape& TopoShape::makeElementPrism(const TopoShape& base, const gp_Vec& vec,
|
||||
|
||||
// TODO: This code was transferred in Feb 2024 as part of the toponaming project, but appears to be
|
||||
// unused. It is potentially useful if debugged.
|
||||
//TopoShape& TopoShape::makeElementPrismUntil(const TopoShape& _base,
|
||||
// TopoShape& TopoShape::makeElementPrismUntil(const TopoShape& _base,
|
||||
// const TopoShape& profile,
|
||||
// const TopoShape& supportFace,
|
||||
// const TopoShape& __uptoface,
|
||||
@@ -4121,9 +4302,9 @@ TopoShape& TopoShape::makeElementPrism(const TopoShape& base, const gp_Vec& vec,
|
||||
// }
|
||||
//
|
||||
// if (remove_limits) {
|
||||
// // Note: Using an unlimited face every time gives unnecessary failures for concave faces
|
||||
// TopLoc_Location loc = face.Location();
|
||||
// BRepAdaptor_Surface adapt(face, Standard_False);
|
||||
// // Note: Using an unlimited face every time gives unnecessary failures for concave
|
||||
// faces TopLoc_Location loc = face.Location(); BRepAdaptor_Surface adapt(face,
|
||||
// Standard_False);
|
||||
// // use the placement of the adapter, not of the upToFace
|
||||
// loc = TopLoc_Location(adapt.Trsf());
|
||||
// BRepBuilderAPI_MakeFace mkFace(adapt.Surface().Surface(), Precision::Confusion());
|
||||
@@ -4656,7 +4837,7 @@ TopoShape& TopoShape::makeElementBSplineFace(const std::vector<TopoShape>& input
|
||||
}
|
||||
unsigned ind = 0;
|
||||
for (auto& edge : newEdges) {
|
||||
if ( ind < edges.size() ) {
|
||||
if (ind < edges.size()) {
|
||||
edge.resetElementMap(edges[ind++].elementMap());
|
||||
}
|
||||
}
|
||||
@@ -5510,33 +5691,32 @@ TopoShape& TopoShape::makeElementBoolean(const char* maker,
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TopoShape::isSame(const Data::ComplexGeoData &_other) const
|
||||
bool TopoShape::isSame(const Data::ComplexGeoData& _other) const
|
||||
{
|
||||
if(!_other.isDerivedFrom(TopoShape::getClassTypeId()))
|
||||
return false;
|
||||
|
||||
const auto &other = static_cast<const TopoShape &>(_other);
|
||||
return Tag == other.Tag
|
||||
&& Hasher == other.Hasher
|
||||
&& _Shape.IsEqual(other._Shape);
|
||||
}
|
||||
void TopoShape::cacheRelatedElements(const Data::MappedName &name,
|
||||
HistoryTraceType sameType,
|
||||
const QVector<Data::MappedElement> & names) const
|
||||
{
|
||||
initCache();
|
||||
_cache->insertRelation(ShapeRelationKey(name,sameType), names);
|
||||
}
|
||||
|
||||
bool TopoShape::getRelatedElementsCached(const Data::MappedName &name,
|
||||
HistoryTraceType sameType,
|
||||
QVector<Data::MappedElement> &names) const
|
||||
{
|
||||
if(!_cache) {
|
||||
if (!_other.isDerivedFrom(TopoShape::getClassTypeId())) {
|
||||
return false;
|
||||
}
|
||||
auto it = _cache->relations.find(ShapeRelationKey(name,sameType));
|
||||
if(it == _cache->relations.end()) {
|
||||
|
||||
const auto& other = static_cast<const TopoShape&>(_other);
|
||||
return Tag == other.Tag && Hasher == other.Hasher && _Shape.IsEqual(other._Shape);
|
||||
}
|
||||
void TopoShape::cacheRelatedElements(const Data::MappedName& name,
|
||||
HistoryTraceType sameType,
|
||||
const QVector<Data::MappedElement>& names) const
|
||||
{
|
||||
initCache();
|
||||
_cache->insertRelation(ShapeRelationKey(name, sameType), names);
|
||||
}
|
||||
|
||||
bool TopoShape::getRelatedElementsCached(const Data::MappedName& name,
|
||||
HistoryTraceType sameType,
|
||||
QVector<Data::MappedElement>& names) const
|
||||
{
|
||||
if (!_cache) {
|
||||
return false;
|
||||
}
|
||||
auto it = _cache->relations.find(ShapeRelationKey(name, sameType));
|
||||
if (it == _cache->relations.end()) {
|
||||
return false;
|
||||
}
|
||||
names = it->second;
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#include "SoBrepFaceSet.h"
|
||||
#include "SoBrepPointSet.h"
|
||||
|
||||
FC_LOG_LEVEL_INIT("Part", true, true)
|
||||
|
||||
using namespace PartGui;
|
||||
namespace sp = std::placeholders;
|
||||
@@ -592,6 +593,16 @@ void DlgFilletEdges::setupFillet(const std::vector<App::DocumentObject*>& objs)
|
||||
{
|
||||
App::DocumentObject* base = d->fillet->Base.getValue();
|
||||
const std::vector<Part::FilletElement>& e = d->fillet->Edges.getValues();
|
||||
const auto &subs = d->fillet->EdgeLinks.getShadowSubs();
|
||||
if(subs.size()!=e.size()) {
|
||||
FC_ERR("edge link size mismatch");
|
||||
return;
|
||||
}
|
||||
std::set<std::string> subSet;
|
||||
for(auto &sub : subs)
|
||||
subSet.insert(sub.first.empty()?sub.second:sub.first);
|
||||
|
||||
std::string tmp;
|
||||
std::vector<App::DocumentObject*>::const_iterator it = std::find(objs.begin(), objs.end(), base);
|
||||
if (it != objs.end()) {
|
||||
// toggle visibility
|
||||
@@ -613,6 +624,40 @@ void DlgFilletEdges::setupFillet(const std::vector<App::DocumentObject*>& objs)
|
||||
std::vector<std::string> subElements;
|
||||
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(ui->treeView->model());
|
||||
bool block = model->blockSignals(true); // do not call toggleCheckState
|
||||
auto baseShape = Part::Feature::getTopoShape(base);
|
||||
std::set<Part::FilletElement> elements;
|
||||
for(size_t i=0;i<e.size();++i) {
|
||||
auto &sub = subs[i];
|
||||
if(sub.first.empty()) {
|
||||
int idx = 0;
|
||||
sscanf(sub.second.c_str(),"Edge%d",&idx);
|
||||
if(idx==0)
|
||||
FC_WARN("missing element reference: " << sub.second);
|
||||
else
|
||||
elements.insert(e[i]);
|
||||
continue;
|
||||
}
|
||||
auto &ref = sub.first;
|
||||
Part::TopoShape edge;
|
||||
try {
|
||||
edge = baseShape.getSubShape(ref.c_str());
|
||||
}catch(...) {}
|
||||
if(!edge.isNull()) {
|
||||
elements.insert(e[i]);
|
||||
continue;
|
||||
}
|
||||
FC_WARN("missing element reference: " << base->getFullName() << "." << ref);
|
||||
|
||||
for(auto &mapped : Part::Feature::getRelatedElements(base,ref.c_str())) {
|
||||
tmp.clear();
|
||||
if(!subSet.insert(mapped.index.appendToStringBuffer(tmp)).second
|
||||
|| !subSet.insert(mapped.name.toString(0)).second)
|
||||
continue;
|
||||
FC_WARN("guess element reference: " << ref << " -> " << mapped.index);
|
||||
elements.emplace(mapped.index.getIndex(),e[i].radius1,e[i].radius2);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto & et : e) {
|
||||
std::vector<int>::iterator it = std::find(d->edge_ids.begin(), d->edge_ids.end(), et.edgeid);
|
||||
if (it != d->edge_ids.end()) {
|
||||
|
||||
@@ -71,7 +71,6 @@ TEST_F(FeatureChamferTest, testOther)
|
||||
// Assert
|
||||
EXPECT_EQ(sec, 24);
|
||||
// Act
|
||||
// _chamfer->Edges.setValues(PartTestHelpers::_getFilletEdges({1, 2}, chamfer, chamfer));
|
||||
_chamfer->Edges.setValues(PartTestHelpers::_getFilletEdges({1, 2}, chamfer, chamfer));
|
||||
double fusedVolume = PartTestHelpers::getVolume(_fused->Shape.getValue());
|
||||
double chamferVolume = PartTestHelpers::getVolume(_chamfer->Shape.getValue());
|
||||
|
||||
@@ -1422,12 +1422,16 @@ TEST_F(TopoShapeExpansionTest, makeElementBooleanCut)
|
||||
// Assert elementMap is correct
|
||||
EXPECT_EQ(elements.size(), 38);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E;:L(Face5;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E|Face5;:M;"
|
||||
"CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V;:L(Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;"
|
||||
"CUT;:H1:7,V);CUT;:H1:3c,E|Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E);CUT;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;CUT;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementBooleanFuse)
|
||||
@@ -1448,12 +1452,16 @@ TEST_F(TopoShapeExpansionTest, makeElementBooleanFuse)
|
||||
// Assert element map is correct
|
||||
EXPECT_EQ(elements.size(), 66);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;"
|
||||
"FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;"
|
||||
"FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementDraft)
|
||||
@@ -1707,12 +1715,16 @@ TEST_F(TopoShapeExpansionTest, makeElementGeneralFuse)
|
||||
// Assert elementMap is correct
|
||||
EXPECT_EQ(elements.size(), 72);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;GFS;:H1:7,F;:U;GFS;:H1:7,E;:L(Face5;:M;GFS;:H1:7,F;:U2;GFS;:H1:8,E|Face5;:M;"
|
||||
"GFS;:H1:7,F;:U2;GFS;:H1:8,E;:U;GFS;:H1:7,V;:L(Face6;:M;GFS;:H1:7,F;:U2;GFS;:H1:8,E;:U;"
|
||||
"GFS;:H1:7,V);GFS;:H1:3c,E|Face6;:M;GFS;:H1:7,F;:U2;GFS;:H1:8,E);GFS;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;GFS;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementFuse)
|
||||
@@ -1732,12 +1744,16 @@ TEST_F(TopoShapeExpansionTest, makeElementFuse)
|
||||
// Assert elementMap is correct
|
||||
EXPECT_EQ(elements.size(), 66);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;"
|
||||
"FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;"
|
||||
"FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementCut)
|
||||
@@ -1758,12 +1774,16 @@ TEST_F(TopoShapeExpansionTest, makeElementCut)
|
||||
// Assert elementMap is correct
|
||||
EXPECT_EQ(elements.size(), 38);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E;:L(Face5;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E|Face5;:M;"
|
||||
"CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V;:L(Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;"
|
||||
"CUT;:H1:7,V);CUT;:H1:3c,E|Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E);CUT;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;CUT;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementChamfer)
|
||||
@@ -2170,12 +2190,16 @@ TEST_F(TopoShapeExpansionTest, makeElementTransformWithMap)
|
||||
// Assert elementMap is correct
|
||||
EXPECT_EQ(elements.size(), 66);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;"
|
||||
"FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;"
|
||||
"FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementGTransformWithoutMap)
|
||||
@@ -2216,12 +2240,16 @@ TEST_F(TopoShapeExpansionTest, makeElementGTransformWithMap)
|
||||
// Assert elementMap is correct
|
||||
EXPECT_EQ(elements.size(), 66);
|
||||
EXPECT_EQ(elements.count(IndexedName("Face", 1)), 1);
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_EQ(
|
||||
elements[IndexedName("Face", 1)],
|
||||
MappedName(
|
||||
"Face3;:M;FUS;:H1:7,F;:U;FUS;:H1:7,E;:L(Face5;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E|Face5;:M;"
|
||||
"FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;FUS;:H1:7,V;:L(Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E;:U;"
|
||||
"FUS;:H1:7,V);FUS;:H1:3c,E|Face6;:M;FUS;:H1:7,F;:U2;FUS;:H1:8,E);FUS;:H1:cb,F"));
|
||||
#else
|
||||
EXPECT_EQ(elements[IndexedName("Face", 1)], MappedName("Face1;FUS;:H1:4,F"));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Not testing _makeElementTransform as it is a thin wrapper that calls the same places as the four
|
||||
@@ -2594,6 +2622,7 @@ TEST_F(TopoShapeExpansionTest, traceElement)
|
||||
// Act
|
||||
result.traceElement(mappedName, cb);
|
||||
// Assert we have the element map we think we do.
|
||||
#ifndef FC_USE_TNP_FIX
|
||||
EXPECT_TRUE(allElementsMatch(
|
||||
result,
|
||||
{
|
||||
@@ -2641,6 +2670,49 @@ TEST_F(TopoShapeExpansionTest, traceElement)
|
||||
"Face6;:M;CUT;:H1:7,F;:U2;CUT;:H1:8,E;:U;CUT;:H1:7,V",
|
||||
"Face6;:M;CUT;:H1:7,F;:U;CUT;:H1:7,E",
|
||||
}));
|
||||
#else
|
||||
EXPECT_TRUE(allElementsMatch(result,
|
||||
{
|
||||
"Edge10;:G(Edge2;K-1;:H2:4,E);CUT;:H1:1a,V",
|
||||
"Edge10;:M;CUT;:H1:7,E",
|
||||
"Edge11;:M;CUT;:H2:7,E",
|
||||
"Edge11;CUT;:H1:4,E",
|
||||
"Edge12;:M;CUT;:H2:7,E",
|
||||
"Edge12;CUT;:H1:4,E",
|
||||
"Edge1;CUT;:H1:4,E",
|
||||
"Edge2;:M;CUT;:H2:7,E",
|
||||
"Edge2;CUT;:H1:4,E",
|
||||
"Edge3;CUT;:H1:4,E",
|
||||
"Edge3;CUT;:H2:4,E",
|
||||
"Edge4;:M;CUT;:H2:7,E",
|
||||
"Edge4;CUT;:H1:4,E",
|
||||
"Edge6;:G(Edge12;K-1;:H2:4,E);CUT;:H1:1b,V",
|
||||
"Edge6;:M;CUT;:H1:7,E",
|
||||
"Edge7;CUT;:H1:4,E",
|
||||
"Edge8;:G(Edge11;K-1;:H2:4,E);CUT;:H1:1b,V",
|
||||
"Edge8;:M;CUT;:H1:7,E",
|
||||
"Edge9;:G(Edge4;K-1;:H2:4,E);CUT;:H1:1a,V",
|
||||
"Edge9;:M;CUT;:H1:7,E",
|
||||
"Face1;:M;CUT;:H2:7,F",
|
||||
"Face1;CUT;:H1:4,F",
|
||||
"Face2;:G(Face4;K-1;:H2:4,F);CUT;:H1:1a,E",
|
||||
"Face2;:M;CUT;:H1:7,F",
|
||||
"Face3;:G(Face1;K-1;:H2:4,F);CUT;:H1:1a,E",
|
||||
"Face3;:M;CUT;:H1:7,F",
|
||||
"Face4;:M;CUT;:H2:7,F",
|
||||
"Face4;CUT;:H1:4,F",
|
||||
"Face5;:M;CUT;:H1:7,F",
|
||||
"Face6;:M;CUT;:H1:7,F",
|
||||
"Vertex1;CUT;:H1:4,V",
|
||||
"Vertex2;CUT;:H1:4,V",
|
||||
"Vertex3;CUT;:H1:4,V",
|
||||
"Vertex3;CUT;:H2:4,V",
|
||||
"Vertex4;CUT;:H1:4,V",
|
||||
"Vertex4;CUT;:H2:4,V",
|
||||
"Vertex7;CUT;:H1:4,V",
|
||||
"Vertex8;CUT;:H1:4,V",
|
||||
}));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, makeElementOffset)
|
||||
|
||||
Reference in New Issue
Block a user