Toposhape/Part: Transfer in makESlice and makEMirror
This commit is contained in:
@@ -218,3 +218,95 @@ TopoDS_Wire CrossSection::fixWire(const TopoDS_Wire& wire) const
|
||||
aFix.FixClosed();
|
||||
return aFix.Wire();
|
||||
}
|
||||
|
||||
TopoCrossSection::TopoCrossSection(double a, double b, double c, const TopoShape& s, const char *op)
|
||||
: a(a), b(b), c(c), shape(s), op(op?op:Part::OpCodes::Slice)
|
||||
{
|
||||
}
|
||||
|
||||
void TopoCrossSection::slice(int idx, double d, std::vector<TopoShape> &wires) const {
|
||||
// Fixes: 0001228: Cross section of Torus in Part Workbench fails or give wrong results
|
||||
// Fixes: 0001137: Incomplete slices when using Part.slice on a torus
|
||||
bool found = false;
|
||||
for(auto &s : shape.getSubTopoShapes(TopAbs_SOLID)) {
|
||||
sliceSolid(idx, d, s, wires);
|
||||
found = true;
|
||||
}
|
||||
if(!found) {
|
||||
for(auto &s : shape.getSubTopoShapes(TopAbs_SHELL)) {
|
||||
sliceNonSolid(idx, d, s, wires);
|
||||
found = true;
|
||||
}
|
||||
if(!found) {
|
||||
for(auto &s : shape.getSubTopoShapes(TopAbs_FACE))
|
||||
sliceNonSolid(idx, d, s, wires);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TopoShape TopoCrossSection::slice(int idx, double d) const {
|
||||
std::vector<TopoShape> wires;
|
||||
slice(idx,d,wires);
|
||||
return TopoShape().makECompound(wires,0,false);
|
||||
}
|
||||
|
||||
void TopoCrossSection::sliceNonSolid(int idx, double d,
|
||||
const TopoShape& shape, std::vector<TopoShape>& wires) const
|
||||
{
|
||||
BRepAlgoAPI_Section cs(shape.getShape(), gp_Pln(a,b,c,-d));
|
||||
if (cs.IsDone()) {
|
||||
std::string prefix(op);
|
||||
if(idx>1) {
|
||||
prefix += '_';
|
||||
prefix += std::to_string(idx);
|
||||
}
|
||||
auto res = TopoShape().makEShape(cs,shape,prefix.c_str()).makEWires().getSubTopoShapes(TopAbs_WIRE);
|
||||
wires.insert(wires.end(),res.begin(),res.end());
|
||||
}
|
||||
}
|
||||
|
||||
void TopoCrossSection::sliceSolid(int idx, double d,
|
||||
const TopoShape& shape, std::vector<TopoShape>& wires) const
|
||||
{
|
||||
gp_Pln slicePlane(a,b,c,-d);
|
||||
BRepBuilderAPI_MakeFace mkFace(slicePlane);
|
||||
TopoShape face(idx);
|
||||
face.setShape(mkFace.Face());
|
||||
|
||||
// Make sure to choose a point that does not lie on the plane (fixes #0001228)
|
||||
gp_Vec tempVector(a,b,c);
|
||||
tempVector.Normalize();//just in case.
|
||||
tempVector *= (d+1.0);
|
||||
gp_Pnt refPoint(0.0, 0.0, 0.0);
|
||||
refPoint.Translate(tempVector);
|
||||
|
||||
BRepPrimAPI_MakeHalfSpace mkSolid(TopoDS::Face(face.getShape()), refPoint);
|
||||
TopoShape solid(idx);
|
||||
std::string prefix(op);
|
||||
if(idx>1) {
|
||||
prefix += '_';
|
||||
prefix += std::to_string(idx);
|
||||
}
|
||||
solid.makEShape(mkSolid,face,prefix.c_str());
|
||||
BRepAlgoAPI_Cut mkCut(shape.getShape(), solid.getShape());
|
||||
|
||||
if (mkCut.IsDone()) {
|
||||
TopoShape res(shape.Tag,shape.Hasher);
|
||||
std::vector<TopoShape> shapes;
|
||||
shapes.push_back(shape);
|
||||
shapes.push_back(solid);
|
||||
res.makEShape(mkCut,shapes,prefix.c_str());
|
||||
for(auto &face : res.getSubTopoShapes(TopAbs_FACE)) {
|
||||
BRepAdaptor_Surface adapt(TopoDS::Face(face.getShape()));
|
||||
if (adapt.GetType() == GeomAbs_Plane) {
|
||||
gp_Pln plane = adapt.Plane();
|
||||
if (plane.Axis().IsParallel(slicePlane.Axis(), Precision::Confusion()) &&
|
||||
plane.Distance(slicePlane.Location()) < Precision::Confusion()) {
|
||||
auto repaired_wires = TopoShape(face.Tag).makEWires(
|
||||
face.getSubTopoShapes(TopAbs_EDGE),prefix.c_str(),true).getSubTopoShapes(TopAbs_WIRE);
|
||||
wires.insert(wires.end(),repaired_wires.begin(),repaired_wires.end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <list>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <Mod/Part/PartGlobal.h>
|
||||
#include "TopoShape.h"
|
||||
|
||||
|
||||
class TopoDS_Shape;
|
||||
@@ -52,6 +53,23 @@ private:
|
||||
const TopoDS_Shape& s;
|
||||
};
|
||||
|
||||
class PartExport TopoCrossSection
|
||||
{
|
||||
public:
|
||||
TopoCrossSection(double a, double b, double c, const TopoShape& s, const char *op=0);
|
||||
void slice(int idx, double d, std::vector<TopoShape> &wires) const;
|
||||
TopoShape slice(int idx, double d) const;
|
||||
|
||||
private:
|
||||
void sliceNonSolid(int idx, double d, const TopoShape&, std::vector<TopoShape>& wires) const;
|
||||
void sliceSolid(int idx, double d, const TopoShape&, std::vector<TopoShape>& wires) const;
|
||||
|
||||
private:
|
||||
double a,b,c;
|
||||
const TopoShape& shape;
|
||||
const char *op;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PART_CROSSSECTION_H
|
||||
|
||||
@@ -1330,6 +1330,89 @@ public:
|
||||
return TopoShape(0, Hasher).makeElementBoolean(maker, *this, op, tol);
|
||||
}
|
||||
|
||||
/** Make a mirrored shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param axis: the axis for mirroring
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
*
|
||||
* @return The original content of this TopoShape is discarded and replaced
|
||||
* with the new shape. 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 &makEMirror(const TopoShape &source, const gp_Ax2& axis, const char *op=nullptr);
|
||||
/** Make a mirrored shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param axis: the axis for mirroring
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
*
|
||||
* @return Return the new shape. The TopoShape itself is not modified.
|
||||
*/
|
||||
TopoShape makEMirror(const gp_Ax2& ax, const char *op=nullptr) const {
|
||||
return TopoShape(0,Hasher).makEMirror(*this,ax,op);
|
||||
}
|
||||
|
||||
/** Make a cross section slice
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param dir: direction of the normal of the section plane
|
||||
* @param d: distance to move the section plane
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
*
|
||||
* @return The original content of this TopoShape is discarded and replaced
|
||||
* with the new shape. 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 &makESlice(const TopoShape &source, const Base::Vector3d& dir, double d, const char *op=nullptr);
|
||||
/** Make a cross section slice
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param dir: direction of the normal of the section plane
|
||||
* @param d: distance to move the section plane
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
*
|
||||
* @return Return the new shape. The TopoShape itself is not modified.
|
||||
*/
|
||||
TopoShape makESlice(const Base::Vector3d& dir, double d, const char *op=nullptr) const {
|
||||
return TopoShape(0,Hasher).makESlice(*this,dir,d,op);
|
||||
}
|
||||
|
||||
/** Make multiple cross section slices
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param dir: direction of the normal of the section plane
|
||||
* @param distances: distances to move the section plane for making slices
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
*
|
||||
* @return The original content of this TopoShape is discarded and replaced
|
||||
* with the new shape. 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 &makESlices(const TopoShape &source, const Base::Vector3d& dir,
|
||||
const std::vector<double> &distances, const char *op=nullptr);
|
||||
/** Make multiple cross section slices
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param dir: direction of the normal of the section plane
|
||||
* @param distances: distances to move the section plane for making slices
|
||||
* @param op: optional string to be encoded into topo naming for indicating
|
||||
* the operation
|
||||
*
|
||||
* @return Return the new shape. The TopoShape itself is not modified.
|
||||
*/
|
||||
TopoShape makESlices(const Base::Vector3d &dir, const std::vector<double> &distances, const char *op=nullptr) const {
|
||||
return TopoShape(0,Hasher).makESlices(*this,dir,distances,op);
|
||||
}
|
||||
|
||||
/* Make fillet shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
|
||||
@@ -2596,6 +2596,30 @@ struct MapperThruSections: MapperMaker
|
||||
}
|
||||
};
|
||||
|
||||
TopoShape &TopoShape::makESlice(const TopoShape &shape,
|
||||
const Base::Vector3d& dir, double d, const char *op)
|
||||
{
|
||||
if(shape.isNull())
|
||||
HANDLE_NULL_SHAPE;
|
||||
TopoCrossSection cs(dir.x, dir.y, dir.z,shape,op);
|
||||
TopoShape res = cs.slice(1,d);
|
||||
setShape(res._Shape);
|
||||
Hasher = res.Hasher;
|
||||
resetElementMap(res.elementMap());
|
||||
return *this;
|
||||
}
|
||||
|
||||
TopoShape &TopoShape::makESlices(const TopoShape &shape,
|
||||
const Base::Vector3d& dir, const std::vector<double> &d, const char *op)
|
||||
{
|
||||
std::vector<TopoShape> wires;
|
||||
TopoCrossSection cs(dir.x, dir.y, dir.z, shape,op);
|
||||
int i=0;
|
||||
for(auto &dd : d)
|
||||
cs.slice(++i,dd,wires);
|
||||
return makECompound(wires,op,false);
|
||||
}
|
||||
|
||||
TopoShape& TopoShape::makeElementFillet(const TopoShape& shape,
|
||||
const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
|
||||
Reference in New Issue
Block a user