Toponaming/Part: Transfer makeElementBoolean in
This commit is contained in:
@@ -911,6 +911,61 @@ public:
|
||||
return TopoShape(Tag, Hasher).makeElementCopy(*this, op, copyGeom, copyMesh);
|
||||
}
|
||||
|
||||
|
||||
/** Generalized shape making with mapped element name from shape history
|
||||
*
|
||||
* @param maker: op code from OpCodes
|
||||
* @param sources: list of source shapes.
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
* @param tol: tolerance option available to some shape making algorithm
|
||||
*
|
||||
* @return The original content of this TopoShape is discarded and replaced
|
||||
* with the new shape built by the shape maker. The function
|
||||
* returns the TopoShape itself as a self reference so that
|
||||
* multiple operations can be carried out for the same shape in the
|
||||
* same line of code.
|
||||
*/
|
||||
TopoShape& makeElementBoolean(const char* maker,
|
||||
const std::vector<TopoShape>& sources,
|
||||
const char* op = nullptr,
|
||||
double tol = 0.0);
|
||||
/** Generalized shape making with mapped element name from shape history
|
||||
*
|
||||
* @param maker: op code from TopoShapeOpCodes
|
||||
* @param source: source shape.
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
* @param tol: tolerance option available to some shape making algorithm
|
||||
*
|
||||
* @return The original content of this TopoShape is discarded and replaced
|
||||
* with the new shape built by the shape maker. The function
|
||||
* returns the TopoShape itself as a self reference so that
|
||||
* multiple operations can be carried out for the same shape in the
|
||||
* same line of code.
|
||||
*/
|
||||
TopoShape& makeElementBoolean(const char* maker,
|
||||
const TopoShape& source,
|
||||
const char* op = nullptr,
|
||||
double tol = 0.0);
|
||||
|
||||
/** Generalized shape making with mapped element name from shape history
|
||||
*
|
||||
* @param maker: op code from TopoShapeOpCodes
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
* @param tol: tolerance option available to some shape making algorithm
|
||||
*
|
||||
* @return Returns the new shape with mappend element name generated from
|
||||
* shape history using this shape as the source. The shape itself
|
||||
* is not modified.
|
||||
*/
|
||||
TopoShape
|
||||
makeElementBoolean(const char* maker, const char* op = nullptr, double tol = 0.0) const
|
||||
{
|
||||
return TopoShape(0, Hasher).makeElementBoolean(maker, *this, op, tol);
|
||||
}
|
||||
|
||||
/* Make a shell using this shape
|
||||
* @param silent: whether to throw exception on failure
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
|
||||
@@ -34,11 +34,26 @@
|
||||
#include <BRepFill_Generator.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepAlgoAPI_BooleanOperation.hxx>
|
||||
#include <BRepAlgoAPI_Common.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
#include <BRepAlgoAPI_Fuse.hxx>
|
||||
#include <BRepAlgoAPI_Section.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
#include <BRepOffsetAPI_MakePipe.hxx>
|
||||
#include <ShapeUpgrade_ShellSewing.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
#include <ShapeUpgrade_ShellSewing.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
|
||||
#include <utility>
|
||||
@@ -46,6 +61,7 @@
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
#include "TopoShape.h"
|
||||
@@ -56,12 +72,27 @@
|
||||
#include "TopoShapeOpCode.h"
|
||||
#include <App/ElementNamingUtils.h>
|
||||
#include <BRepLib.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
|
||||
FC_LOG_LEVEL_INIT("TopoShape", true, true) // NOLINT
|
||||
|
||||
namespace Part
|
||||
{
|
||||
|
||||
static void expandCompound(const TopoShape& shape, std::vector<TopoShape>& res)
|
||||
{
|
||||
if (shape.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
if (shape.getShape().ShapeType() != TopAbs_COMPOUND) {
|
||||
res.push_back(shape);
|
||||
return;
|
||||
}
|
||||
for (auto& s : shape.getSubTopoShapes()) {
|
||||
expandCompound(s, res);
|
||||
}
|
||||
}
|
||||
|
||||
void TopoShape::initCache(int reset) const
|
||||
{
|
||||
if (reset > 0 || !_cache || _cache->isTouched(_Shape)) {
|
||||
@@ -2362,4 +2393,227 @@ bool TopoShape::fixSolidOrientation()
|
||||
return false;
|
||||
}
|
||||
|
||||
TopoShape&
|
||||
TopoShape::makeElementBoolean(const char* maker, const TopoShape& shape, const char* op, double tolerance)
|
||||
{
|
||||
return makeElementBoolean(maker, std::vector<TopoShape>(1, shape), op, tolerance);
|
||||
}
|
||||
|
||||
|
||||
TopoShape& TopoShape::makeElementBoolean(const char* maker,
|
||||
const std::vector<TopoShape>& shapes,
|
||||
const char* op,
|
||||
double tolerance)
|
||||
{
|
||||
#if OCC_VERSION_HEX <= 0x060800
|
||||
if (tolerance > 0.0) {
|
||||
Standard_Failure::Raise("Fuzzy Booleans are not supported in this version of OCCT");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!maker) {
|
||||
FC_THROWM(Base::CADKernelError, "no maker");
|
||||
}
|
||||
|
||||
if (!op) {
|
||||
op = maker;
|
||||
}
|
||||
|
||||
if (shapes.empty()) {
|
||||
FC_THROWM(NullShapeException, "Null shape");
|
||||
}
|
||||
|
||||
if (strcmp(maker, Part::OpCodes::Compound) == 0) {
|
||||
return makeElementCompound(shapes, op, SingleShapeCompoundCreationPolicy::returnShape);
|
||||
}
|
||||
else if (boost::starts_with(maker, Part::OpCodes::Face)) {
|
||||
std::string prefix(Part::OpCodes::Face);
|
||||
prefix += '.';
|
||||
const char* face_maker = 0;
|
||||
if (boost::starts_with(maker, prefix)) {
|
||||
face_maker = maker + prefix.size();
|
||||
}
|
||||
return makeElementFace(shapes, op, face_maker);
|
||||
}
|
||||
else if (strcmp(maker, Part::OpCodes::Wire) == 0) {
|
||||
return makeElementWires(shapes, op);
|
||||
}
|
||||
else if (strcmp(maker, Part::OpCodes::Compsolid) == 0) {
|
||||
BRep_Builder builder;
|
||||
TopoDS_CompSolid Comp;
|
||||
builder.MakeCompSolid(Comp);
|
||||
for (auto& s : shapes) {
|
||||
if (!s.isNull()) {
|
||||
builder.Add(Comp, s.getShape());
|
||||
}
|
||||
}
|
||||
setShape(Comp);
|
||||
mapSubElement(shapes, op);
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (strcmp(maker, Part::OpCodes::Pipe) == 0) {
|
||||
if (shapes.size() != 2) {
|
||||
FC_THROWM(Base::CADKernelError, "Not enough input shapes");
|
||||
}
|
||||
if (shapes[0].isNull() || shapes[1].isNull()) {
|
||||
FC_THROWM(Base::CADKernelError, "Cannot sweep along empty spine");
|
||||
}
|
||||
if (shapes[0].getShape().ShapeType() != TopAbs_WIRE) {
|
||||
FC_THROWM(Base::CADKernelError, "Spine shape is not a wire");
|
||||
}
|
||||
BRepOffsetAPI_MakePipe mkPipe(TopoDS::Wire(shapes[0].getShape()), shapes[1].getShape());
|
||||
return makeElementShape(mkPipe, shapes, op);
|
||||
}
|
||||
|
||||
if (strcmp(maker, Part::OpCodes::Shell) == 0) {
|
||||
BRep_Builder builder;
|
||||
TopoDS_Shell shell;
|
||||
builder.MakeShell(shell);
|
||||
for (auto& s : shapes) {
|
||||
builder.Add(shell, s.getShape());
|
||||
}
|
||||
setShape(shell);
|
||||
mapSubElement(shapes, op);
|
||||
BRepCheck_Analyzer check(shell);
|
||||
if (!check.IsValid()) {
|
||||
ShapeUpgrade_ShellSewing sewShell;
|
||||
setShape(sewShell.ApplySewing(shell), false);
|
||||
// TODO confirm the above won't change OCCT topological naming
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool buildShell = true;
|
||||
|
||||
std::vector<TopoShape> _shapes;
|
||||
if (strcmp(maker, Part::OpCodes::Fuse) == 0) {
|
||||
for (auto it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
auto& s = *it;
|
||||
if (s.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
if (s.shapeType() == TopAbs_COMPOUND) {
|
||||
if (_shapes.empty()) {
|
||||
_shapes.insert(_shapes.end(), shapes.begin(), it);
|
||||
}
|
||||
expandCompound(s, _shapes);
|
||||
}
|
||||
else if (_shapes.size()) {
|
||||
_shapes.push_back(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (strcmp(maker, Part::OpCodes::Cut) == 0) {
|
||||
for (unsigned i = 1; i < shapes.size(); ++i) {
|
||||
auto& s = shapes[i];
|
||||
if (s.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
if (s.shapeType() == TopAbs_COMPOUND) {
|
||||
if (_shapes.empty()) {
|
||||
_shapes.insert(_shapes.end(), shapes.begin(), shapes.begin() + i);
|
||||
}
|
||||
expandCompound(s, _shapes);
|
||||
}
|
||||
else if (_shapes.size()) {
|
||||
_shapes.push_back(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tolerance > 0.0 && _shapes.empty()) {
|
||||
_shapes = shapes;
|
||||
}
|
||||
|
||||
const auto& inputs = _shapes.size() ? _shapes : shapes;
|
||||
if (inputs.empty()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
if (inputs.size() == 1) {
|
||||
*this = inputs[0];
|
||||
if (shapes.size() == 1) {
|
||||
// _shapes has fewer items than shapes due to compound expansion.
|
||||
// Only warn if the caller paseses one shape.
|
||||
FC_WARN("Boolean operation with only one shape input");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::unique_ptr<BRepAlgoAPI_BooleanOperation> mk;
|
||||
if (strcmp(maker, Part::OpCodes::Fuse) == 0) {
|
||||
mk.reset(new BRepAlgoAPI_Fuse);
|
||||
}
|
||||
else if (strcmp(maker, Part::OpCodes::Cut) == 0) {
|
||||
mk.reset(new BRepAlgoAPI_Cut);
|
||||
}
|
||||
else if (strcmp(maker, Part::OpCodes::Common) == 0) {
|
||||
mk.reset(new BRepAlgoAPI_Common);
|
||||
}
|
||||
else if (strcmp(maker, Part::OpCodes::Section) == 0) {
|
||||
mk.reset(new BRepAlgoAPI_Section);
|
||||
buildShell = false;
|
||||
}
|
||||
else {
|
||||
FC_THROWM(Base::CADKernelError, "Unknown maker");
|
||||
}
|
||||
|
||||
TopTools_ListOfShape shapeArguments, shapeTools;
|
||||
|
||||
int i = -1;
|
||||
for (const auto& shape : inputs) {
|
||||
if (shape.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
if (++i == 0) {
|
||||
shapeArguments.Append(shape.getShape());
|
||||
}
|
||||
else if (tolerance > 0.0) {
|
||||
auto& s = _shapes[i];
|
||||
// workaround for http://dev.opencascade.org/index.php?q=node/1056#comment-520
|
||||
s.setShape(BRepBuilderAPI_Copy(s.getShape()).Shape(), false);
|
||||
shapeTools.Append(s.getShape());
|
||||
}
|
||||
else {
|
||||
shapeTools.Append(shape.getShape());
|
||||
}
|
||||
}
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x070500
|
||||
// Can't find this threshold value anywhere. Go ahead assuming it is true.
|
||||
// if (PartParams::getParallelRunThreshold() > 0) {
|
||||
mk->SetRunParallel(Standard_True);
|
||||
OSD_Parallel::SetUseOcctThreads(Standard_True);
|
||||
// }
|
||||
#else
|
||||
// Only run parallel
|
||||
if (shapeArguments.Size() + shapeTools.Size() > 2) {
|
||||
mk->SetRunParallel(true);
|
||||
}
|
||||
else if (PartParams::getParallelRunThreshold() > 0) {
|
||||
int total = 0;
|
||||
for (const auto& shape : inputs) {
|
||||
total += shape.countSubShapes(TopAbs_FACE);
|
||||
if (total > PartParams::getParallelRunThreshold()) {
|
||||
mk->SetRunParallel(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mk->SetArguments(shapeArguments);
|
||||
mk->SetTools(shapeTools);
|
||||
if (tolerance > 0.0) {
|
||||
mk->SetFuzzyValue(tolerance);
|
||||
}
|
||||
mk->Build();
|
||||
makeElementShape(*mk, inputs, op);
|
||||
|
||||
if (buildShell) {
|
||||
makeElementShell();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace Part
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
// NOLINTBEGIN(readability-magic-numbers,cppcoreguidelines-avoid-magic-numbers)
|
||||
|
||||
using namespace Part;
|
||||
using namespace PartTestHelpers;
|
||||
|
||||
class TopoShapeExpansionTest: public ::testing::Test
|
||||
@@ -53,13 +54,13 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundOneShapeReturnsShape)
|
||||
{
|
||||
// Arrange
|
||||
auto edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
Part::TopoShape topoShape {edge};
|
||||
std::vector<Part::TopoShape> shapes {topoShape};
|
||||
TopoShape topoShape {edge};
|
||||
std::vector<TopoShape> shapes {topoShape};
|
||||
|
||||
// Act
|
||||
topoShape.makeElementCompound(shapes,
|
||||
"C",
|
||||
Part::TopoShape::SingleShapeCompoundCreationPolicy::
|
||||
TopoShape::SingleShapeCompoundCreationPolicy::
|
||||
returnShape /*Don't force the creation*/);
|
||||
|
||||
// Assert
|
||||
@@ -70,14 +71,14 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundOneShapeForceReturnsCompound)
|
||||
{
|
||||
// Arrange
|
||||
auto edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
Part::TopoShape topoShape {edge};
|
||||
std::vector<Part::TopoShape> shapes {topoShape};
|
||||
TopoShape topoShape {edge};
|
||||
std::vector<TopoShape> shapes {topoShape};
|
||||
|
||||
// Act
|
||||
topoShape.makeElementCompound(
|
||||
shapes,
|
||||
"C",
|
||||
Part::TopoShape::SingleShapeCompoundCreationPolicy::forceCompound /*Force the creation*/);
|
||||
TopoShape::SingleShapeCompoundCreationPolicy::forceCompound /*Force the creation*/);
|
||||
|
||||
// Assert
|
||||
EXPECT_NE(edge.ShapeType(), topoShape.getShape().ShapeType()); // No longer the same thing
|
||||
@@ -88,8 +89,8 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundTwoShapesReturnsCompound)
|
||||
// Arrange
|
||||
auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
auto edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1.0, 0.0, 0.0), gp_Pnt(2.0, 0.0, 0.0)).Edge();
|
||||
Part::TopoShape topoShape {edge1};
|
||||
std::vector<Part::TopoShape> shapes {edge1, edge2};
|
||||
TopoShape topoShape {edge1};
|
||||
std::vector<TopoShape> shapes {edge1, edge2};
|
||||
|
||||
// Act
|
||||
topoShape.makeElementCompound(shapes);
|
||||
@@ -102,8 +103,8 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundEmptyShapesReturnsEmptyCompoun
|
||||
{
|
||||
// Arrange
|
||||
auto edge = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
Part::TopoShape topoShape {edge};
|
||||
std::vector<Part::TopoShape> shapes;
|
||||
TopoShape topoShape {edge};
|
||||
std::vector<TopoShape> shapes;
|
||||
|
||||
// Act
|
||||
topoShape.makeElementCompound(shapes);
|
||||
@@ -121,8 +122,8 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundTwoShapesGeneratesMap)
|
||||
// Arrange
|
||||
auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
auto edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1.0, 0.0, 0.0), gp_Pnt(2.0, 0.0, 0.0)).Edge();
|
||||
Part::TopoShape topoShape {edge1};
|
||||
std::vector<Part::TopoShape> shapes {edge1, edge2};
|
||||
TopoShape topoShape {edge1};
|
||||
std::vector<TopoShape> shapes {edge1, edge2};
|
||||
|
||||
// Act
|
||||
topoShape.makeElementCompound(shapes);
|
||||
@@ -135,13 +136,13 @@ TEST_F(TopoShapeExpansionTest, makeElementCompoundTwoCubes)
|
||||
{
|
||||
// Arrange
|
||||
auto [cube1, cube2] = CreateTwoCubes();
|
||||
Part::TopoShape cube1TS {cube1};
|
||||
TopoShape cube1TS {cube1};
|
||||
cube1TS.Tag = 1;
|
||||
Part::TopoShape cube2TS {cube2};
|
||||
TopoShape cube2TS {cube2};
|
||||
cube2TS.Tag = 2;
|
||||
|
||||
// Act
|
||||
Part::TopoShape topoShape;
|
||||
TopoShape topoShape;
|
||||
topoShape.makeElementCompound({cube1TS, cube2TS});
|
||||
|
||||
// Assert
|
||||
@@ -261,8 +262,8 @@ TEST_F(TopoShapeExpansionTest, MapperMakerGenerated)
|
||||
// // Arrange
|
||||
// auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
// auto edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(1.0, 0.0, 0.0), gp_Pnt(2.0, 0.0, 0.0)).Edge();
|
||||
// Part::TopoShape topoShape;
|
||||
// std::vector<Part::TopoShape> shapes {edge1, edge2};
|
||||
// TopoShape topoShape;
|
||||
// std::vector<TopoShape> shapes {edge1, edge2};
|
||||
|
||||
// // Act
|
||||
// topoShape.makeElementWires(shapes);
|
||||
@@ -281,11 +282,11 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceNull)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {face1};
|
||||
TopoShape topoShape {face1};
|
||||
double area = getArea(face1);
|
||||
double area1 = getArea(topoShape.getShape());
|
||||
// Act
|
||||
Part::TopoShape newFace = topoShape.makeElementFace(nullptr);
|
||||
TopoShape newFace = topoShape.makeElementFace(nullptr);
|
||||
double area2 = getArea(newFace.getShape());
|
||||
double area3 = getArea(topoShape.getShape());
|
||||
// Assert
|
||||
@@ -304,11 +305,11 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceSimple)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {face1};
|
||||
TopoShape topoShape {face1};
|
||||
double area = getArea(face1);
|
||||
double area1 = getArea(topoShape.getShape());
|
||||
// Act
|
||||
Part::TopoShape newFace = topoShape.makeElementFace(wire1);
|
||||
TopoShape newFace = topoShape.makeElementFace(wire1);
|
||||
double area2 = getArea(newFace.getShape());
|
||||
double area3 = getArea(topoShape.getShape());
|
||||
// Assert
|
||||
@@ -328,11 +329,11 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceParams)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {face1, 1L};
|
||||
TopoShape topoShape {face1, 1L};
|
||||
double area = getArea(face1);
|
||||
double area1 = getArea(topoShape.getShape());
|
||||
// Act
|
||||
Part::TopoShape newFace =
|
||||
TopoShape newFace =
|
||||
topoShape.makeElementFace(wire1, "Cut", "Part::FaceMakerBullseye", nullptr);
|
||||
double area2 = getArea(newFace.getShape());
|
||||
double area3 = getArea(topoShape.getShape());
|
||||
@@ -353,11 +354,11 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceFromFace)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {face1, 1L};
|
||||
TopoShape topoShape {face1, 1L};
|
||||
double area = getArea(face1);
|
||||
double area1 = getArea(topoShape.getShape());
|
||||
// Act
|
||||
Part::TopoShape newFace =
|
||||
TopoShape newFace =
|
||||
topoShape.makeElementFace(face1, "Cut", "Part::FaceMakerBullseye", nullptr);
|
||||
double area2 = getArea(newFace.getShape());
|
||||
double area3 = getArea(topoShape.getShape());
|
||||
@@ -379,11 +380,11 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceOpenWire)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {wire1, 1L};
|
||||
TopoShape topoShape {wire1, 1L};
|
||||
double area = getArea(face1);
|
||||
double area1 = getArea(topoShape.getShape());
|
||||
// Act
|
||||
Part::TopoShape newFace = topoShape.makeElementFace(wire1, "Cut", nullptr, nullptr);
|
||||
TopoShape newFace = topoShape.makeElementFace(wire1, "Cut", nullptr, nullptr);
|
||||
double area2 = getArea(newFace.getShape());
|
||||
double area3 = getArea(topoShape.getShape());
|
||||
// Assert
|
||||
@@ -404,11 +405,11 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceClosedWire)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {wire2, 1L};
|
||||
TopoShape topoShape {wire2, 1L};
|
||||
double area = getArea(face1);
|
||||
double area1 = getArea(topoShape.getShape());
|
||||
// Act
|
||||
Part::TopoShape newFace =
|
||||
TopoShape newFace =
|
||||
topoShape.makeElementFace(wire2, "Cut", "Part::FaceMakerBullseye", nullptr);
|
||||
double area2 = getArea(newFace.getShape());
|
||||
double area3 = getArea(topoShape.getShape());
|
||||
@@ -432,7 +433,7 @@ TEST_F(TopoShapeExpansionTest, makeElementFaceClosedWire)
|
||||
TEST_F(TopoShapeExpansionTest, setElementComboNameNothing)
|
||||
{
|
||||
// Arrange
|
||||
Part::TopoShape topoShape(1L);
|
||||
TopoShape topoShape(1L);
|
||||
// Act
|
||||
Data::MappedName result = topoShape.setElementComboName(Data::IndexedName(), {});
|
||||
// ASSERT
|
||||
@@ -444,7 +445,7 @@ TEST_F(TopoShapeExpansionTest, setElementComboNameSimple)
|
||||
{
|
||||
// Arrange
|
||||
auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
Part::TopoShape topoShape(edge1, 1L);
|
||||
TopoShape topoShape(edge1, 1L);
|
||||
topoShape.setElementMap({}); // Initialize the map to avoid a segfault.
|
||||
// Also, maybe the end of TopoShape::mapSubElementTypeForShape should enforce that elementMap()
|
||||
// isn't nullptr to eliminate the segfault.
|
||||
@@ -460,7 +461,7 @@ TEST_F(TopoShapeExpansionTest, setElementComboNameSimple)
|
||||
TEST_F(TopoShapeExpansionTest, setElementComboName)
|
||||
{
|
||||
// Arrange
|
||||
Part::TopoShape topoShape(2L);
|
||||
TopoShape topoShape(2L);
|
||||
topoShape.setElementMap({});
|
||||
Data::MappedName edgeName =
|
||||
topoShape.getMappedName(Data::IndexedName::fromConst("Edge", 1), true);
|
||||
@@ -472,7 +473,7 @@ TEST_F(TopoShapeExpansionTest, setElementComboName)
|
||||
// Act
|
||||
Data::MappedName result = topoShape.setElementComboName(Data::IndexedName::fromConst("Edge", 1),
|
||||
{edgeName, faceName, faceName2},
|
||||
Part::OpCodes::Common,
|
||||
OpCodes::Common,
|
||||
op);
|
||||
// Assert
|
||||
EXPECT_STREQ(result.toString().c_str(), "Edge1;CMN(Face7|Face8);Copy");
|
||||
@@ -485,7 +486,7 @@ TEST_F(TopoShapeExpansionTest, setElementComboNameCompound)
|
||||
auto edge1 = BRepBuilderAPI_MakeEdge(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(1.0, 0.0, 0.0)).Edge();
|
||||
auto wire1 = BRepBuilderAPI_MakeWire({edge1}).Wire();
|
||||
auto wire2 = BRepBuilderAPI_MakeWire({edge1}).Wire();
|
||||
Part::TopoShape topoShape(2L);
|
||||
TopoShape topoShape(2L);
|
||||
topoShape.makeElementCompound({wire1, wire2}); // Quality of shape doesn't matter
|
||||
Data::MappedName edgeName =
|
||||
topoShape.getMappedName(Data::IndexedName::fromConst("Edge", 1), true);
|
||||
@@ -497,7 +498,7 @@ TEST_F(TopoShapeExpansionTest, setElementComboNameCompound)
|
||||
// Act
|
||||
Data::MappedName result = topoShape.setElementComboName(Data::IndexedName::fromConst("Edge", 1),
|
||||
{edgeName, faceName, faceName2},
|
||||
Part::OpCodes::Common,
|
||||
OpCodes::Common,
|
||||
op);
|
||||
// ASSERT
|
||||
EXPECT_STREQ(result.toString().c_str(), "Edge1;:H,E;CMN(Face7|Face8);Copy");
|
||||
@@ -511,18 +512,18 @@ TEST_F(TopoShapeExpansionTest, splitWires)
|
||||
const float Wid = 2;
|
||||
const float Rad = 1;
|
||||
auto [face1, wire1, wire2] = CreateFaceWithRoundHole(Len, Wid, Rad);
|
||||
Part::TopoShape topoShape {face1, 1L};
|
||||
std::vector<Part::TopoShape> inner;
|
||||
TopoShape topoShape {face1, 1L};
|
||||
std::vector<TopoShape> inner;
|
||||
// Act
|
||||
EXPECT_EQ(topoShape.getShape().Orientation(), TopAbs_FORWARD);
|
||||
Part::TopoShape wire =
|
||||
topoShape.splitWires(&inner, Part::TopoShape::SplitWireReorient::ReorientReversed);
|
||||
TopoShape wire =
|
||||
topoShape.splitWires(&inner, TopoShape::SplitWireReorient::ReorientReversed);
|
||||
// Assert
|
||||
EXPECT_EQ(inner.size(), 1);
|
||||
EXPECT_FLOAT_EQ(getLength(wire.getShape()), 2 + 2 + 3 + 3);
|
||||
EXPECT_FLOAT_EQ(getLength(inner.front().getShape()), M_PI * Rad * 2);
|
||||
EXPECT_EQ(wire.getShape().Orientation(), TopAbs_REVERSED);
|
||||
for (Part::TopoShape& shape : inner) {
|
||||
for (TopoShape& shape : inner) {
|
||||
EXPECT_EQ(shape.getShape().Orientation(), TopAbs_FORWARD);
|
||||
}
|
||||
}
|
||||
@@ -536,28 +537,28 @@ TEST_F(TopoShapeExpansionTest, mapSubElementInvalidParm)
|
||||
{
|
||||
// Arrange
|
||||
auto [cube1, cube2] = CreateTwoCubes();
|
||||
Part::TopoShape cube1TS {cube1};
|
||||
TopoShape cube1TS {cube1};
|
||||
cube1TS.Tag = 1;
|
||||
|
||||
// Act
|
||||
std::vector<Part::TopoShape> subShapes = cube1TS.getSubTopoShapes(TopAbs_FACE);
|
||||
Part::TopoShape face1 = subShapes.front();
|
||||
std::vector<TopoShape> subShapes = cube1TS.getSubTopoShapes(TopAbs_FACE);
|
||||
TopoShape face1 = subShapes.front();
|
||||
face1.Tag = 2;
|
||||
|
||||
// Assert
|
||||
EXPECT_THROW(cube1TS.mapSubElement(face1), Part::NullShapeException); // No subshapes
|
||||
EXPECT_THROW(cube1TS.mapSubElement(face1), NullShapeException); // No subshapes
|
||||
}
|
||||
|
||||
TEST_F(TopoShapeExpansionTest, mapSubElementFindShapeByNames)
|
||||
{
|
||||
// Arrange
|
||||
auto [cube1, cube2] = CreateTwoCubes();
|
||||
Part::TopoShape cube1TS {cube1};
|
||||
Part::TopoShape cube2TS {cube2};
|
||||
TopoShape cube1TS {cube1};
|
||||
TopoShape cube2TS {cube2};
|
||||
cube1TS.Tag = 1;
|
||||
cube2TS.Tag = 2;
|
||||
Part::TopoShape topoShape;
|
||||
Part::TopoShape topoShape1;
|
||||
TopoShape topoShape;
|
||||
TopoShape topoShape1;
|
||||
|
||||
// Act
|
||||
int fs1 = topoShape1.findShape(cube1);
|
||||
@@ -585,11 +586,11 @@ TEST_F(TopoShapeExpansionTest, mapSubElementFindShapeByType)
|
||||
{
|
||||
// Arrange
|
||||
auto [cube1, cube2] = CreateTwoCubes();
|
||||
Part::TopoShape cube1TS {cube1};
|
||||
Part::TopoShape cube2TS {cube2};
|
||||
TopoShape cube1TS {cube1};
|
||||
TopoShape cube2TS {cube2};
|
||||
cube1TS.Tag = 1;
|
||||
cube2TS.Tag = 2;
|
||||
Part::TopoShape topoShape;
|
||||
TopoShape topoShape;
|
||||
topoShape.makeElementCompound({cube1TS, cube2TS});
|
||||
topoShape.mapSubElement(cube2TS, "Name", false);
|
||||
|
||||
@@ -607,11 +608,11 @@ TEST_F(TopoShapeExpansionTest, mapSubElementFindAncestor)
|
||||
{
|
||||
// Arrange
|
||||
auto [cube1, cube2] = CreateTwoCubes();
|
||||
Part::TopoShape cube1TS {cube1};
|
||||
Part::TopoShape cube2TS {cube2};
|
||||
TopoShape cube1TS {cube1};
|
||||
TopoShape cube2TS {cube2};
|
||||
cube1TS.Tag = 1;
|
||||
cube2TS.Tag = 2;
|
||||
Part::TopoShape topoShape;
|
||||
TopoShape topoShape;
|
||||
topoShape.makeElementCompound({cube1TS, cube2TS});
|
||||
topoShape.mapSubElement(cube2TS, "Name", false);
|
||||
|
||||
@@ -634,21 +635,21 @@ TEST_F(TopoShapeExpansionTest, mapSubElementFindAncestors)
|
||||
tr.SetTranslation(gp_Vec(gp_XYZ(0, 1, 0)));
|
||||
cube3.Move(TopLoc_Location(tr));
|
||||
cube4.Move(TopLoc_Location(tr));
|
||||
Part::TopoShape cube1TS {cube1};
|
||||
Part::TopoShape cube2TS {cube2};
|
||||
Part::TopoShape cube3TS {cube3};
|
||||
Part::TopoShape cube4TS {cube4};
|
||||
TopoShape cube1TS {cube1};
|
||||
TopoShape cube2TS {cube2};
|
||||
TopoShape cube3TS {cube3};
|
||||
TopoShape cube4TS {cube4};
|
||||
cube1TS.Tag = 1;
|
||||
cube2TS.Tag = 2;
|
||||
cube3TS.Tag = 3;
|
||||
cube4TS.Tag = 4;
|
||||
Part::TopoShape topoShape;
|
||||
Part::TopoShape topoShape1;
|
||||
Part::TopoShape topoShape2;
|
||||
Part::TopoShape topoShape3;
|
||||
Part::TopoShape topoShape4;
|
||||
Part::TopoShape topoShape5;
|
||||
Part::TopoShape topoShape6;
|
||||
TopoShape topoShape;
|
||||
TopoShape topoShape1;
|
||||
TopoShape topoShape2;
|
||||
TopoShape topoShape3;
|
||||
TopoShape topoShape4;
|
||||
TopoShape topoShape5;
|
||||
TopoShape topoShape6;
|
||||
topoShape.makeElementCompound({cube1TS, cube2TS});
|
||||
topoShape1.makeElementCompound({cube3TS, cube4TS});
|
||||
topoShape2.makeElementCompound({cube1TS, cube3TS});
|
||||
@@ -688,7 +689,7 @@ TEST_F(TopoShapeExpansionTest, mapSubElementFindAncestors)
|
||||
TEST_F(TopoShapeExpansionTest, makeElementShellInvalid)
|
||||
{
|
||||
// Arrange
|
||||
Part::TopoShape topoShape {1L};
|
||||
TopoShape topoShape {1L};
|
||||
// Act / Assert
|
||||
EXPECT_THROW(topoShape.makeElementShell(false, nullptr), Base::CADKernelError);
|
||||
}
|
||||
@@ -699,9 +700,9 @@ TEST_F(TopoShapeExpansionTest, makeElementShellSingle)
|
||||
const float Len = 3;
|
||||
const float Wid = 2;
|
||||
auto [face1, wire1, edge1, edge2, edge3, _] = CreateRectFace(Len, Wid);
|
||||
Part::TopoShape topoShape {face1, 1L};
|
||||
TopoShape topoShape {face1, 1L};
|
||||
// Act
|
||||
Part::TopoShape result = topoShape.makeElementShell(false, nullptr);
|
||||
TopoShape result = topoShape.makeElementShell(false, nullptr);
|
||||
// Assert
|
||||
#if OCC_VERSION_HEX >= 0x070400
|
||||
EXPECT_EQ(result.getShape().NbChildren(), 1);
|
||||
@@ -727,9 +728,9 @@ TEST_F(TopoShapeExpansionTest, makeElementShellOpen)
|
||||
builder.MakeCompound(compound1);
|
||||
builder.Add(compound1, face1);
|
||||
builder.Add(compound1, face2);
|
||||
Part::TopoShape topoShape {compound1, 1L};
|
||||
TopoShape topoShape {compound1, 1L};
|
||||
// Act
|
||||
Part::TopoShape result = topoShape.makeElementShell(true, nullptr);
|
||||
TopoShape result = topoShape.makeElementShell(true, nullptr);
|
||||
// Assert
|
||||
#if OCC_VERSION_HEX >= 0x070400
|
||||
EXPECT_EQ(result.getShape().NbChildren(), 2);
|
||||
@@ -744,16 +745,16 @@ TEST_F(TopoShapeExpansionTest, makeElementShellClosed)
|
||||
{
|
||||
// Arrange
|
||||
auto [cube1, cube2] = CreateTwoCubes();
|
||||
Part::TopoShape topoShape {cube1};
|
||||
std::vector<Part::TopoShape> shapes;
|
||||
TopoShape topoShape {cube1};
|
||||
std::vector<TopoShape> shapes;
|
||||
for (const auto& face : topoShape.getSubShapes(TopAbs_FACE)) {
|
||||
shapes.emplace_back(face);
|
||||
}
|
||||
// Act
|
||||
Part::TopoShape topoShape1 {1L};
|
||||
TopoShape topoShape1 {1L};
|
||||
topoShape1.makeElementCompound(shapes, "D");
|
||||
// Assert
|
||||
Part::TopoShape result = topoShape1.makeElementShell(false, "SH1");
|
||||
TopoShape result = topoShape1.makeElementShell(false, "SH1");
|
||||
#if OCC_VERSION_HEX >= 0x070400
|
||||
EXPECT_EQ(result.getShape().NbChildren(), 6);
|
||||
#endif
|
||||
@@ -770,8 +771,8 @@ TEST_F(TopoShapeExpansionTest, makeElementShellIntersecting)
|
||||
auto transform {gp_Trsf()};
|
||||
transform.SetTranslation(gp_Pnt(0.0, 0.0, 0.0), gp_Pnt(0.5, 0.5, 0.0));
|
||||
cube2.Move(TopLoc_Location(transform));
|
||||
Part::TopoShape topoShape {cube1};
|
||||
std::vector<Part::TopoShape> shapes;
|
||||
TopoShape topoShape {cube1};
|
||||
std::vector<TopoShape> shapes;
|
||||
for (const auto& face : topoShape.getSubShapes(TopAbs_FACE)) {
|
||||
shapes.emplace_back(face);
|
||||
}
|
||||
@@ -780,7 +781,7 @@ TEST_F(TopoShapeExpansionTest, makeElementShellIntersecting)
|
||||
shapes.emplace_back(face);
|
||||
}
|
||||
// Act
|
||||
Part::TopoShape topoShape1 {1L};
|
||||
TopoShape topoShape1 {1L};
|
||||
topoShape1.makeElementCompound(shapes, "D");
|
||||
// Assert
|
||||
EXPECT_THROW(topoShape1.makeElementShell(false, nullptr), Base::CADKernelError);
|
||||
|
||||
Reference in New Issue
Block a user