Merge branch 'main' into bgbsww-toponamingMakeElementSolid
This commit is contained in:
@@ -112,7 +112,7 @@ installed addons will be checked for available updates
|
||||
<string>Hide Addons with non-FSF Free/Libre license</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>HideNonFSFFreeLibre</cstring>
|
||||
|
||||
@@ -502,7 +502,6 @@ if HAVE_QTNETWORK:
|
||||
current_index = index
|
||||
break
|
||||
|
||||
sender.abort()
|
||||
if current_index != -1:
|
||||
self.__launch_request(current_index, self.__create_get_request(url, timeout_ms))
|
||||
|
||||
@@ -579,7 +578,7 @@ if HAVE_QTNETWORK:
|
||||
return
|
||||
|
||||
response_code = reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)
|
||||
if response_code == 301: # Permanently moved -- this is a redirect, bail out
|
||||
if response_code == 301 or response_code == 302: # This is a redirect, bail out
|
||||
return
|
||||
if reply.error() != QtNetwork.QNetworkReply.NetworkError.OperationCanceledError:
|
||||
# It this was not a timeout, make sure we mark the queue task done
|
||||
|
||||
@@ -93,9 +93,9 @@ class PackageList(QtWidgets.QWidget):
|
||||
self.set_view_style(style)
|
||||
self.ui.view_bar.view_selector.set_current_view(style)
|
||||
|
||||
self.item_filter.setHidePy2(pref.GetBool("HidePy2", True))
|
||||
self.item_filter.setHideObsolete(pref.GetBool("HideObsolete", True))
|
||||
self.item_filter.setHideNonOSIApproved(pref.GetBool("HideNonOSIApproved", True))
|
||||
self.item_filter.setHidePy2(pref.GetBool("HidePy2", False))
|
||||
self.item_filter.setHideObsolete(pref.GetBool("HideObsolete", False))
|
||||
self.item_filter.setHideNonOSIApproved(pref.GetBool("HideNonOSIApproved", False))
|
||||
self.item_filter.setHideNonFSFLibre(pref.GetBool("HideNonFSFFreeLibre", False))
|
||||
self.item_filter.setHideNewerFreeCADRequired(
|
||||
pref.GetBool("HideNewerFreeCADRequired", False)
|
||||
|
||||
@@ -2508,4 +2508,21 @@ def compact_mesh(
|
||||
# may be return another value if the mesh was compacted, just check last map entries
|
||||
return (new_mesh, node_map, elem_map)
|
||||
|
||||
# ************************************************************************************************
|
||||
def beam_reduced_integration(
|
||||
fileName
|
||||
):
|
||||
# replace B3x elements with B3xR elements
|
||||
f = open(fileName, "r+")
|
||||
lines = f.readlines()
|
||||
f.seek(0)
|
||||
for line in lines:
|
||||
if line.find("B32") != -1:
|
||||
line = line.replace("B32", "B32R")
|
||||
if line.find("B31") != -1:
|
||||
line = line.replace("B31", "B31R")
|
||||
f.write(line)
|
||||
|
||||
f.truncate()
|
||||
f.close()
|
||||
## @}
|
||||
|
||||
@@ -372,6 +372,15 @@ def add_attributes(obj, ccx_prefs):
|
||||
obj.BeamShellResultOutput3D = dimout
|
||||
|
||||
|
||||
if not hasattr(obj, "BeamReducedIntegration"):
|
||||
obj.addProperty(
|
||||
"App::PropertyBool",
|
||||
"BeamReducedIntegration",
|
||||
"Fem",
|
||||
"Set to True to use beam elements with reduced integration"
|
||||
)
|
||||
obj.BeamReducedIntegration = True
|
||||
|
||||
"""
|
||||
Should there be some equation object for Calculix too?
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ def write_femelement_geometry(f, ccxwriter):
|
||||
thickness = beamsec_obj.PipeThickness.getValueAs("mm").Value
|
||||
section_type = ", SECTION=PIPE"
|
||||
section_geo = "{:.13G},{:.13G}\n".format(radius, thickness)
|
||||
section_def = "*BEAM GENERAL SECTION, {}{}{}\n".format(
|
||||
section_def = "*BEAM SECTION, {}{}{}\n".format(
|
||||
elsetdef,
|
||||
material,
|
||||
section_type
|
||||
|
||||
@@ -51,6 +51,10 @@ def write_mesh(ccxwriter):
|
||||
if ccxwriter.member.geos_fluidsection:
|
||||
meshtools.write_D_network_element_to_inputfile(ccxwriter.femmesh_file)
|
||||
|
||||
# Use reduced integration beam elements if this option is enabled in ccx solver settings
|
||||
if ccxwriter.solver_obj.BeamReducedIntegration:
|
||||
meshtools.beam_reduced_integration(ccxwriter.femmesh_file)
|
||||
|
||||
inpfile = codecs.open(ccxwriter.file_name, "w", encoding="utf-8")
|
||||
inpfile.write("{}\n".format(59 * "*"))
|
||||
inpfile.write("** {}\n".format(write_name))
|
||||
@@ -69,6 +73,10 @@ def write_mesh(ccxwriter):
|
||||
# inpfile is closed
|
||||
meshtools.write_D_network_element_to_inputfile(ccxwriter.femmesh_file)
|
||||
|
||||
# Use reduced integration beam elements if this option is enabled in ccx solver settings
|
||||
if ccxwriter.solver_obj.BeamReducedIntegration:
|
||||
meshtools.beam_reduced_integration(ccxwriter.femmesh_file)
|
||||
|
||||
# reopen file with "append" to add all the rest
|
||||
inpfile = codecs.open(ccxwriter.femmesh_file, "a", encoding="utf-8")
|
||||
inpfile.write("\n\n")
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
** Edge elements
|
||||
*Element, TYPE=B32, ELSET=Eedges
|
||||
*Element, TYPE=B32R, ELSET=Eedges
|
||||
1, 1, 7, 3
|
||||
2, 3, 8, 4
|
||||
3, 4, 9, 5
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
** Edge elements
|
||||
*Element, TYPE=B32, ELSET=Eedges
|
||||
*Element, TYPE=B32R, ELSET=Eedges
|
||||
1, 1, 7, 3
|
||||
2, 3, 8, 4
|
||||
3, 4, 9, 5
|
||||
@@ -56,7 +56,7 @@ Eedges
|
||||
|
||||
***********************************************************
|
||||
** Sections
|
||||
*BEAM GENERAL SECTION, ELSET=M0B0RstdD0, MATERIAL=MechanicalMaterial, SECTION=PIPE
|
||||
*BEAM SECTION, ELSET=M0B0RstdD0, MATERIAL=MechanicalMaterial, SECTION=PIPE
|
||||
500,100
|
||||
-0, 1, 0
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
** Edge elements
|
||||
*Element, TYPE=B32, ELSET=Eedges
|
||||
*Element, TYPE=B32R, ELSET=Eedges
|
||||
1, 1, 7, 3
|
||||
2, 3, 8, 4
|
||||
3, 4, 9, 5
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
|
||||
** Edge elements
|
||||
*Element, TYPE=B31, ELSET=Eedges
|
||||
*Element, TYPE=B31R, ELSET=Eedges
|
||||
1, 1, 3
|
||||
2, 3, 4
|
||||
3, 4, 5
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
** Edge elements
|
||||
*Element, TYPE=B32, ELSET=Eedges
|
||||
*Element, TYPE=B32R, ELSET=Eedges
|
||||
1, 1, 7, 3
|
||||
2, 3, 8, 4
|
||||
3, 4, 9, 5
|
||||
|
||||
@@ -593,14 +593,6 @@ void TopoShape::setPyObject(PyObject* obj)
|
||||
}
|
||||
}
|
||||
|
||||
void TopoShape::operator = (const TopoShape& sh)
|
||||
{
|
||||
if (this != &sh) {
|
||||
this->Tag = sh.Tag;
|
||||
this->_Shape = sh._Shape;
|
||||
}
|
||||
}
|
||||
|
||||
void TopoShape::convertTogpTrsf(const Base::Matrix4D& mtrx, gp_Trsf& trsf)
|
||||
{
|
||||
trsf.SetValues(mtrx[0][0],mtrx[0][1],mtrx[0][2],mtrx[0][3],
|
||||
|
||||
@@ -197,9 +197,33 @@ enum class MapElement
|
||||
/// Defines how to fill the holes that may appear after offset two adjacent faces
|
||||
enum class JoinType
|
||||
{
|
||||
Arc,
|
||||
Tangent,
|
||||
Intersection,
|
||||
arc,
|
||||
tangent,
|
||||
intersection,
|
||||
};
|
||||
|
||||
enum class Flip
|
||||
{
|
||||
none,
|
||||
flip
|
||||
};
|
||||
|
||||
enum class AsAngle
|
||||
{
|
||||
no,
|
||||
yes
|
||||
};
|
||||
|
||||
enum class CheckScale
|
||||
{
|
||||
noScaleCheck,
|
||||
checkScale
|
||||
};
|
||||
|
||||
enum class Copy
|
||||
{
|
||||
noCopy,
|
||||
copy
|
||||
};
|
||||
|
||||
enum class CheckScale
|
||||
@@ -820,7 +844,7 @@ public:
|
||||
*/
|
||||
TopoShape &makeElementThickSolid(const TopoShape &shape, const std::vector<TopoShape> &faces,
|
||||
double offset, double tol, bool intersection = false, bool selfInter = false,
|
||||
short offsetMode = 0, JoinType join = JoinType::Arc, const char *op=nullptr);
|
||||
short offsetMode = 0, JoinType join = JoinType::arc, const char *op=nullptr);
|
||||
|
||||
/** Make a hollowed solid by removing some faces from a given solid
|
||||
*
|
||||
@@ -841,7 +865,7 @@ public:
|
||||
*/
|
||||
TopoShape makeElementThickSolid(const std::vector<TopoShape> &faces,
|
||||
double offset, double tol, bool intersection = false, bool selfInter = false,
|
||||
short offsetMode = 0, JoinType join = JoinType::Arc, const char *op=nullptr) const {
|
||||
short offsetMode = 0, JoinType join = JoinType::arc, const char *op=nullptr) const {
|
||||
return TopoShape(0,Hasher).makeElementThickSolid(*this,faces,offset,tol,intersection,selfInter,
|
||||
offsetMode,join,op);
|
||||
}
|
||||
@@ -1015,6 +1039,10 @@ public:
|
||||
void mapSubElementsTo(std::vector<TopoShape>& shapes, const char* op = nullptr) const;
|
||||
bool hasPendingElementMap() const;
|
||||
|
||||
void flushElementMap() const override;
|
||||
|
||||
virtual Data::ElementMapPtr resetElementMap(
|
||||
Data::ElementMapPtr elementMap=Data::ElementMapPtr());
|
||||
|
||||
/** Helper class to return the generated and modified shape given an input shape
|
||||
*
|
||||
@@ -1362,6 +1390,87 @@ public:
|
||||
return TopoShape(0, Hasher).makeElementBoolean(maker, *this, op, tol);
|
||||
}
|
||||
|
||||
/* Make fillet shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param edges: the edges of the source shape where to make fillets
|
||||
* @param radius1: the radius of the beginning of the fillet
|
||||
* @param radius2: the radius of the ending of the fillet
|
||||
* @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& makeElementFillet(const TopoShape& source,
|
||||
const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
double radius2,
|
||||
const char* op = nullptr);
|
||||
/* Make fillet shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param edges: the edges of the source shape where to make fillets
|
||||
* @param radius1: the radius of the beginning of the fillet
|
||||
* @param radius2: the radius of the ending of the fillet
|
||||
* @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 makeElementFillet(const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
double radius2,
|
||||
const char* op = nullptr) const
|
||||
{
|
||||
return TopoShape(0, Hasher).makeElementFillet(*this, edges, radius1, radius2, op);
|
||||
}
|
||||
|
||||
/* Make chamfer shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param edges: the edges of the source shape where to make chamfers
|
||||
* @param radius1: the radius of the beginning of the chamfer
|
||||
* @param radius2: the radius of the ending of the chamfer
|
||||
* @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& makeElementChamfer(const TopoShape& source,
|
||||
const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
double radius2,
|
||||
const char* op = nullptr,
|
||||
Flip flipDirection = Flip::none,
|
||||
AsAngle asAngle = AsAngle::no);
|
||||
/* Make chamfer shape
|
||||
*
|
||||
* @param source: the source shape
|
||||
* @param edges: the edges of the source shape where to make chamfers
|
||||
* @param radius1: the radius of the beginning of the chamfer
|
||||
* @param radius2: the radius of the ending of the chamfer
|
||||
* @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 makeElementChamfer(const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
double radius2,
|
||||
const char* op = nullptr,
|
||||
Flip flipDirection = Flip::none,
|
||||
AsAngle asAngle = AsAngle::no) const
|
||||
{
|
||||
return TopoShape(0, Hasher)
|
||||
.makeElementChamfer(*this, edges, radius1, radius2, op, flipDirection, asAngle);
|
||||
}
|
||||
|
||||
/** Make a new shape with transformation
|
||||
*
|
||||
* @param source: input shape
|
||||
@@ -1430,7 +1539,7 @@ public:
|
||||
TopoShape makeElementTransform(const Base::Matrix4D& mat,
|
||||
const char* op = nullptr,
|
||||
CheckScale checkScale = CheckScale::noScaleCheck,
|
||||
Copy copy = Copy::noCopy)
|
||||
Copy copy = Copy::noCopy) const
|
||||
{
|
||||
return TopoShape(Tag, Hasher).makeElementTransform(*this, mat, op, checkScale, copy);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
#include <BRepBuilderAPI_GTransform.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeSolid.hxx>
|
||||
#include <BRepFilletAPI_MakeChamfer.hxx>
|
||||
#include <BRepFilletAPI_MakeFillet.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRepLib.hxx>
|
||||
#include <BRepOffsetAPI_DraftAngle.hxx>
|
||||
@@ -121,6 +123,48 @@ void TopoShape::initCache(int reset) const
|
||||
}
|
||||
}
|
||||
|
||||
Data::ElementMapPtr TopoShape::resetElementMap(Data::ElementMapPtr elementMap)
|
||||
{
|
||||
if (_cache && elementMap != this->elementMap(false)) {
|
||||
for (auto& info : _cache->shapeAncestryCache) {
|
||||
info.clear();
|
||||
}
|
||||
}
|
||||
else {
|
||||
initCache();
|
||||
}
|
||||
if (elementMap) {
|
||||
_cache->cachedElementMap = elementMap;
|
||||
_cache->subLocation.Identity();
|
||||
_subLocation.Identity();
|
||||
_parentCache.reset();
|
||||
}
|
||||
return Data::ComplexGeoData::resetElementMap(elementMap);
|
||||
}
|
||||
|
||||
void TopoShape::flushElementMap() const
|
||||
{
|
||||
initCache();
|
||||
if (!elementMap(false) && this->_cache) {
|
||||
if (this->_cache->cachedElementMap) {
|
||||
const_cast<TopoShape*>(this)->resetElementMap(this->_cache->cachedElementMap);
|
||||
}
|
||||
else if (this->_parentCache) {
|
||||
TopoShape parent(this->Tag, this->Hasher, this->_parentCache->shape);
|
||||
parent._cache = _parentCache;
|
||||
parent.flushElementMap();
|
||||
TopoShape self(this->Tag,
|
||||
this->Hasher,
|
||||
this->_Shape.Located(this->_subLocation * this->_cache->subLocation));
|
||||
self._cache = _cache;
|
||||
self.mapSubElement(parent);
|
||||
this->_parentCache.reset();
|
||||
this->_subLocation.Identity();
|
||||
const_cast<TopoShape*>(this)->resetElementMap(self.elementMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TopoShape::setShape(const TopoDS_Shape& shape, bool resetElementMap)
|
||||
{
|
||||
if (resetElementMap) {
|
||||
@@ -208,6 +252,18 @@ TopoDS_Shape TopoShape::located(const TopoDS_Shape& tds, const gp_Trsf& transfer
|
||||
return moved(sCopy, transfer);
|
||||
}
|
||||
|
||||
void TopoShape::operator = (const TopoShape& sh)
|
||||
{
|
||||
if (this != &sh) {
|
||||
this->setShape(sh._Shape, true);
|
||||
this->Tag = sh.Tag;
|
||||
this->Hasher = sh.Hasher;
|
||||
this->_cache = sh._cache;
|
||||
this->_parentCache = sh._parentCache;
|
||||
this->_subLocation = sh._subLocation;
|
||||
resetElementMap(sh.elementMap(false));
|
||||
}
|
||||
}
|
||||
|
||||
int TopoShape::findShape(const TopoDS_Shape& subshape) const
|
||||
{
|
||||
@@ -2090,11 +2146,11 @@ TopoShape& TopoShape::makeElementThickSolid(const TopoShape& shape,
|
||||
|
||||
// we do not offer tangent join type
|
||||
switch (join) {
|
||||
case JoinType::Arc:
|
||||
case JoinType::Intersection:
|
||||
case JoinType::arc:
|
||||
case JoinType::intersection:
|
||||
break;
|
||||
default:
|
||||
join = JoinType::Intersection;
|
||||
join = JoinType::intersection;
|
||||
}
|
||||
|
||||
if (shape.isNull()) {
|
||||
@@ -2452,19 +2508,19 @@ TopoShape& TopoShape::makeElementOrderedWires(const std::vector<TopoShape>& shap
|
||||
}
|
||||
|
||||
bool TopoShape::_makeElementTransform(const TopoShape& shape,
|
||||
const Base::Matrix4D& rclTrf,
|
||||
const Base::Matrix4D& mat,
|
||||
const char* op,
|
||||
CheckScale checkScale,
|
||||
Copy copy)
|
||||
{
|
||||
if (checkScale == CheckScale::checkScale) {
|
||||
auto scaleType = rclTrf.hasScale();
|
||||
auto scaleType = mat.hasScale();
|
||||
if (scaleType != Base::ScaleType::NoScaling && scaleType != Base::ScaleType::Uniform) {
|
||||
makeElementGTransform(shape, rclTrf, op, copy);
|
||||
makeElementGTransform(shape, mat, op, copy);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
makeElementTransform(shape, convert(rclTrf), op, copy);
|
||||
makeElementTransform(shape, convert(mat), op, copy);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2475,8 +2531,11 @@ TopoShape& TopoShape::makeElementTransform(const TopoShape& shape,
|
||||
{
|
||||
if (copy == Copy::noCopy) {
|
||||
// OCCT checks the ScaleFactor against gp::Resolution() which is DBL_MIN!!!
|
||||
copy = trsf.ScaleFactor() * trsf.HVectorialPart().Determinant() < 0.
|
||||
|| Abs(Abs(trsf.ScaleFactor()) - 1) > Precision::Confusion() ? Copy::copy : Copy::noCopy;
|
||||
// No scaling is 1 as in 1:1
|
||||
const bool scaling = Abs(Abs(trsf.ScaleFactor()) - 1) > Precision::Confusion();
|
||||
const bool negative_scaling =
|
||||
trsf.ScaleFactor() * trsf.HVectorialPart().Determinant() < 0.0;
|
||||
copy = negative_scaling || scaling ? Copy::copy : Copy::noCopy;
|
||||
}
|
||||
TopoShape tmp(shape);
|
||||
if (copy == Copy::copy) {
|
||||
@@ -2512,7 +2571,7 @@ TopoShape& TopoShape::makeElementTransform(const TopoShape& shape,
|
||||
}
|
||||
|
||||
TopoShape& TopoShape::makeElementGTransform(const TopoShape& shape,
|
||||
const Base::Matrix4D& rclTrf,
|
||||
const Base::Matrix4D& mat,
|
||||
const char* op,
|
||||
Copy copy)
|
||||
{
|
||||
@@ -2521,23 +2580,23 @@ TopoShape& TopoShape::makeElementGTransform(const TopoShape& shape,
|
||||
}
|
||||
|
||||
// if(!op) op = Part::OpCodes::Gtransform;
|
||||
gp_GTrsf mat;
|
||||
mat.SetValue(1, 1, rclTrf[0][0]);
|
||||
mat.SetValue(2, 1, rclTrf[1][0]);
|
||||
mat.SetValue(3, 1, rclTrf[2][0]);
|
||||
mat.SetValue(1, 2, rclTrf[0][1]);
|
||||
mat.SetValue(2, 2, rclTrf[1][1]);
|
||||
mat.SetValue(3, 2, rclTrf[2][1]);
|
||||
mat.SetValue(1, 3, rclTrf[0][2]);
|
||||
mat.SetValue(2, 3, rclTrf[1][2]);
|
||||
mat.SetValue(3, 3, rclTrf[2][2]);
|
||||
mat.SetValue(1, 4, rclTrf[0][3]);
|
||||
mat.SetValue(2, 4, rclTrf[1][3]);
|
||||
mat.SetValue(3, 4, rclTrf[2][3]);
|
||||
gp_GTrsf matrix;
|
||||
matrix.SetValue(1, 1, mat[0][0]);
|
||||
matrix.SetValue(2, 1, mat[1][0]);
|
||||
matrix.SetValue(3, 1, mat[2][0]);
|
||||
matrix.SetValue(1, 2, mat[0][1]);
|
||||
matrix.SetValue(2, 2, mat[1][1]);
|
||||
matrix.SetValue(3, 2, mat[2][1]);
|
||||
matrix.SetValue(1, 3, mat[0][2]);
|
||||
matrix.SetValue(2, 3, mat[1][2]);
|
||||
matrix.SetValue(3, 3, mat[2][2]);
|
||||
matrix.SetValue(1, 4, mat[0][3]);
|
||||
matrix.SetValue(2, 4, mat[1][3]);
|
||||
matrix.SetValue(3, 4, mat[2][3]);
|
||||
|
||||
// geometric transformation
|
||||
TopoShape tmp(shape);
|
||||
BRepBuilderAPI_GTransform mkTrf(shape.getShape(), mat, copy == Copy::copy);
|
||||
BRepBuilderAPI_GTransform mkTrf(shape.getShape(), matrix, copy == Copy::copy);
|
||||
tmp.setShape(mkTrf.Shape(), false);
|
||||
if (op || (shape.Tag && shape.Tag != Tag)) {
|
||||
setShape(tmp._Shape);
|
||||
@@ -2700,6 +2759,80 @@ TopoShape& TopoShape::makeElementSolid(const TopoShape& shape, const char* op)
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
TopoShape& TopoShape::makeElementFillet(const TopoShape& shape,
|
||||
const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
double radius2,
|
||||
const char* op)
|
||||
{
|
||||
if (!op) {
|
||||
op = Part::OpCodes::Fillet;
|
||||
}
|
||||
if (shape.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null shape");
|
||||
}
|
||||
|
||||
if (edges.empty()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
BRepFilletAPI_MakeFillet mkFillet(shape.getShape());
|
||||
for (auto& e : edges) {
|
||||
if (e.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
const auto& edge = e.getShape();
|
||||
if (!shape.findShape(edge)) {
|
||||
FC_THROWM(Base::CADKernelError, "edge does not belong to the shape");
|
||||
}
|
||||
mkFillet.Add(radius1, radius2, TopoDS::Edge(edge));
|
||||
}
|
||||
return makeElementShape(mkFillet, shape, op);
|
||||
}
|
||||
|
||||
TopoShape& TopoShape::makeElementChamfer(const TopoShape& shape,
|
||||
const std::vector<TopoShape>& edges,
|
||||
double radius1,
|
||||
double radius2,
|
||||
const char* op,
|
||||
Flip flipDirection,
|
||||
AsAngle asAngle)
|
||||
{
|
||||
if (!op) {
|
||||
op = Part::OpCodes::Chamfer;
|
||||
}
|
||||
if (shape.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null shape");
|
||||
}
|
||||
if (edges.empty()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
BRepFilletAPI_MakeChamfer mkChamfer(shape.getShape());
|
||||
for (auto& e : edges) {
|
||||
const auto& edge = e.getShape();
|
||||
if (e.isNull()) {
|
||||
FC_THROWM(NullShapeException, "Null input shape");
|
||||
}
|
||||
if (!shape.findShape(edge)) {
|
||||
FC_THROWM(Base::CADKernelError, "edge does not belong to the shape");
|
||||
}
|
||||
// Add edge to fillet algorithm
|
||||
TopoDS_Shape face;
|
||||
if (flipDirection == Flip::flip) {
|
||||
face = shape.findAncestorsShapes(edge, TopAbs_FACE).back();
|
||||
}
|
||||
else {
|
||||
face = shape.findAncestorShape(edge, TopAbs_FACE);
|
||||
}
|
||||
if (asAngle == AsAngle::yes) {
|
||||
mkChamfer.AddDA(radius1, radius2, TopoDS::Edge(edge), TopoDS::Face(face));
|
||||
}
|
||||
else {
|
||||
mkChamfer.Add(radius1, radius2, TopoDS::Edge(edge), TopoDS::Face(face));
|
||||
}
|
||||
}
|
||||
return makeElementShape(mkChamfer, shape, op);
|
||||
}
|
||||
|
||||
TopoShape& TopoShape::makeElementGeneralFuse(const std::vector<TopoShape>& _shapes,
|
||||
std::vector<std::vector<TopoShape>>& modifies,
|
||||
|
||||
Reference in New Issue
Block a user