[TD]improve ComplexSection handling of bad section normal choice

This commit is contained in:
wandererfan
2025-04-26 18:48:05 -04:00
parent 101da159ec
commit c33fe5f274
6 changed files with 754 additions and 424 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -35,19 +35,36 @@
namespace TechDraw
{
class TechDrawExport AlignedSizeResponse
{
public:
AlignedSizeResponse(const TopoDS_Shape& piece, Base::Vector3d size, double zvalue) :
alignedPiece(piece),
pieceSize(size),
zMax(zvalue) {}
TopoDS_Shape alignedPiece;
Base::Vector3d pieceSize;
double zMax;
};
//NOLINTBEGIN
class TechDrawExport DrawComplexSection: public DrawViewSection
{
PROPERTY_HEADER_WITH_OVERRIDE(TechDraw::DrawComplexSection);
//NOLINTEND
public:
DrawComplexSection();
~DrawComplexSection() override = default;
//NOLINTBEGIN
App::PropertyLink CuttingToolWireObject;
App::PropertyEnumeration ProjectionStrategy;//Offset or Aligned
//NOLINTEND
TopoDS_Shape makeCuttingTool(double dMax) override;
gp_Ax2 getCSFromBase(const std::string sectionName) const override;
gp_Ax2 getCSFromBase(const std::string& sectionName) const override;
bool isBaseValid() const override;
TopoDS_Compound findSectionPlaneIntersections(const TopoDS_Shape& cutShape) override;
TopoDS_Shape prepareShape(const TopoDS_Shape& cutShape, double shapeSize) override;
@@ -60,13 +77,10 @@ public:
void makeSectionCut(const TopoDS_Shape& baseShape) override;
void waitingForAlign(bool s) { m_waitingForAlign = s; }
bool waitingForAlign(void) const { return m_waitingForAlign; }
bool waitingForAlign() const { return m_waitingForAlign; }
TopoDS_Shape getShapeForDetail() const override;
public Q_SLOTS:
void onSectionCutFinished(void) override;
bool boxesIntersect(TopoDS_Face& face, TopoDS_Shape& shape);
TopoDS_Shape shapeShapeIntersect(const TopoDS_Shape& shape0, const TopoDS_Shape& shape1);
std::vector<TopoDS_Face> faceShapeIntersect(const TopoDS_Face& face, const TopoDS_Shape& shape);
@@ -81,26 +95,65 @@ public Q_SLOTS:
ChangePointVector getChangePointsFromSectionLine() override;
bool validateProfilePosition(TopoDS_Wire profileWire, gp_Ax2 sectionCS,
gp_Dir& gClosestBasis) const;
bool validateProfilePosition(const TopoDS_Wire& profileWire, const gp_Ax2& sectionCS) const;
bool showSegment(gp_Dir segmentNormal) const;
gp_Vec projectVector(const gp_Vec& vec) const;
TopoDS_Wire makeProfileWire() const;
static TopoDS_Wire makeProfileWire(App::DocumentObject* toolObj);
static TopoDS_Wire makeNoseToTailWire(TopoDS_Wire inWire);
static gp_Vec makeProfileVector(TopoDS_Wire profileWire);
static TopoDS_Wire makeNoseToTailWire(const TopoDS_Wire& inWire);
static gp_Vec makeProfileVector(const TopoDS_Wire& profileWire);
static bool isProfileObject(App::DocumentObject* obj);
static bool isMultiSegmentProfile(App::DocumentObject* obj);
static bool isLinearProfile(App::DocumentObject* obj);
static bool isTrulyEmpty(TopoDS_Shape inShape);
static bool isTrulyEmpty(const TopoDS_Shape& inShape);
static bool canBuild(gp_Ax2 sectionCS, App::DocumentObject* profileObject);
static gp_Vec projectVector(const gp_Vec& vec, gp_Ax2 sectionCS);
static std::pair<Base::Vector3d, Base::Vector3d> getSegmentEnds(const TopoDS_Edge& segment);
static std::pair<Base::Vector3d, Base::Vector3d> getWireEnds(const TopoDS_Wire& wire);
public Q_SLOTS:
void onSectionCutFinished() override;
private:
gp_Dir getFaceNormal(TopoDS_Face& face);
bool validateOffsetProfile(TopoDS_Wire profile, Base::Vector3d direction, double angleThresholdDeg) const;
std::pair<Base::Vector3d, Base::Vector3d> getSegmentEnds(TopoDS_Edge segment) const;
Base::Vector3d getReferenceAxis();
// methods refactored out of makeAlignedPieces
bool getReversers(const gp_Vec& gProfileVector, double& horizReverser, double& verticalReverser);
AlignedSizeResponse getAlignedSize(const TopoDS_Shape& pieceRotated, int iPiece) const;
TopoDS_Shape cutAndRotatePiece(const TopoDS_Shape& rawShape,
const TopoDS_Face& segmentFace,
int iPiece,
Base::Vector3d uOrientedSegmentNormal,
Base::Vector3d uRotateAxis,
double& pieceVertical);
TopoDS_Shape movePieceToPaperPlane(const TopoDS_Shape& piece, double sizeMax);
TopoDS_Shape distributePiece(const TopoDS_Shape& piece,
double pieceSize,
double verticalDisplace,
const gp_Vec& alignmentAxis,
const gp_Vec& gMovementVector,
double baseDistance);
std::vector<std::pair<int, Base::Vector3d> >
getSegmentViewDirections(const TopoDS_Wire& profileWire,
Base::Vector3d sectionNormal,
Base::Vector3d referenceAxis) const;
std::vector<Base::Vector3d> getPointsForClosingProfile(const TopoDS_Wire& profileWire,
double dMax);
static std::vector<TopoDS_Edge> getUniqueEdges(const TopoDS_Wire& wireIn);
static TopoDS_Shape removeEmptyShapes(const TopoDS_Shape& roughTool);
static gp_Dir getFaceNormal(TopoDS_Face& face);
static bool faceContainsEndpoints(const TopoDS_Edge& edgeToMatch,
const TopoDS_Face& faceToSearch);
static bool normalLess(const std::pair<int, Base::Vector3d>& n1,
const std::pair<int, Base::Vector3d>& n2);
static TopoDS_Wire closeProfile(const TopoDS_Wire& profileWire, Base::Vector3d referenceAxis, double dMax);
static TopoDS_Shape profileToSolid(const TopoDS_Wire& closedProfileWire, Base::Vector3d referenceAxis, double dMax);
TopoDS_Shape m_toolFaceShape;
TopoDS_Shape m_alignResult;
@@ -111,7 +164,7 @@ private:
QFuture<void> m_alignFuture;
bool m_waitingForAlign;
static const char* ProjectionStrategyEnums[];
static const char* ProjectionStrategyEnums[]; //NOLINT
};
using DrawComplexSectionPython = App::FeaturePythonT<DrawComplexSection>;

View File

@@ -119,7 +119,7 @@ DrawViewPart::DrawViewPart()
ADD_PROPERTY_TYPE(Direction, (0.0, -1.0, 0.0), group, App::Prop_None,
"Projection Plane normal. The direction you are looking from.");
ADD_PROPERTY_TYPE(XDirection, (0.0, 0.0, 0.0), group, App::Prop_None,
ADD_PROPERTY_TYPE(XDirection, (1.0, 0.0, 0.0), group, App::Prop_None,
"Projection Plane X Axis in R3. Rotates/Mirrors View");
ADD_PROPERTY_TYPE(Perspective, (false), group, App::Prop_None,
"Perspective(true) or Orthographic(false) projection");
@@ -170,17 +170,17 @@ DrawViewPart::~DrawViewPart()
//! returns a compound of all the shapes from the DocumentObjects in the Source &
//! XSource property lists
TopoDS_Shape DrawViewPart::getSourceShape(bool fuse) const
TopoDS_Shape DrawViewPart::getSourceShape(bool fuse, bool allow2d) const
{
// Base::Console().Message("DVP::getSourceShape()\n");
const std::vector<App::DocumentObject*>& links = getAllSources();
if (links.empty()) {
return TopoDS_Shape();
return {};
}
if (fuse) {
return ShapeExtractor::getShapesFused(links);
}
return ShapeExtractor::getShapes(links);
return ShapeExtractor::getShapes(links, allow2d);
}
//! deliver a shape appropriate for making a detail view based on this view
@@ -278,8 +278,14 @@ void DrawViewPart::onChanged(const App::Property* prop)
// Otherwise bad things will happen because there'll be a normalization for direction calculations later.
Base::Vector3d dir = Direction.getValue();
if (DrawUtil::fpCompare(dir.Length(), 0.0)) {
Base::Console().Warning("%s Direction is null. Using (0, -1, 0).\n", Label.getValue());
Direction.setValue(Base::Vector3d(0.0, -1.0, 0.0));
}
Base::Vector3d xdir = XDirection.getValue();
if (DrawUtil::fpCompare(xdir.Length(), 0.0)) {
Base::Console().Warning("%s XDirection is null. Using (1, 0, 0).\n", Label.getValue());
XDirection.setValue(Base::Vector3d(1.0, 0.0, 0.0));
}
DrawView::onChanged(prop);
}

View File

@@ -212,7 +212,7 @@ public:
bool newFaceFinder();
bool isUnsetting() { return nowUnsetting; }
virtual TopoDS_Shape getSourceShape(bool fuse = false) const;
virtual TopoDS_Shape getSourceShape(bool fuse = false, bool allow2d = true) const;
virtual TopoDS_Shape getShapeForDetail() const;
std::vector<App::DocumentObject*> getAllSources() const;

View File

@@ -161,8 +161,10 @@ DrawViewSection::DrawViewSection()
App::Prop_None,
"2D View source for this Section");
BaseView.setScope(App::LinkScope::Global);
// default of (0, -1, 0) matches 'Front' direction in DVP
ADD_PROPERTY_TYPE(SectionNormal,
(0, 0, 1.0),
(0, -1, 0),
sgroup,
App::Prop_None,
"Section Plane normal direction");// direction of extrusion
@@ -250,8 +252,11 @@ DrawViewSection::DrawViewSection()
SvgIncluded.setStatus(App::Property::ReadOnly, true);
PatIncluded.setStatus(App::Property::ReadOnly, true);
// SectionNormal is used instead to Direction
Direction.setStatus(App::Property::ReadOnly, true);
Direction.setValue(SectionNormal.getValue());
SectionDirection.setStatus(App::Property::Hidden, true);
SectionDirection.setStatus(App::Property::ReadOnly, true);
}
@@ -260,7 +265,6 @@ DrawViewSection::~DrawViewSection()
{
// don't destroy this object while it has dependent threads running
if (m_cutFuture.isRunning()) {
Base::Console().Message("%s is waiting for tasks to complete\n", Label.getValue());
m_cutFuture.waitForFinished();
}
}
@@ -268,7 +272,7 @@ DrawViewSection::~DrawViewSection()
short DrawViewSection::mustExecute() const
{
if (isRestoring()) {
return TechDraw::DrawView::mustExecute();
return TechDraw::DrawView::mustExecute(); //NOLINT
}
if (Scale.isTouched() || Direction.isTouched() || BaseView.isTouched()
@@ -276,7 +280,7 @@ short DrawViewSection::mustExecute() const
return 1;
}
return TechDraw::DrawView::mustExecute();
return TechDraw::DrawView::mustExecute(); //NOLINT
}
void DrawViewSection::onChanged(const App::Property* prop)
@@ -293,40 +297,47 @@ void DrawViewSection::onChanged(const App::Property* prop)
return;
}
if (prop == &SectionNormal) {
if (prop == &SectionNormal ||
prop == &XDirection) {
Direction.setValue(SectionNormal.getValue());
return;
}
else if (prop == &SectionSymbol) {
if (prop == &SectionSymbol) {
if (getBaseDVP()) {
getBaseDVP()->requestPaint();
}
return;
}
else if (prop == &CutSurfaceDisplay) {
if (prop == &CutSurfaceDisplay) {
if (CutSurfaceDisplay.isValue("PatHatch")) {
makeLineSets();
}
requestPaint();
return;
}
else if (prop == &FileHatchPattern) {
if (prop == &FileHatchPattern) {
replaceSvgIncluded(FileHatchPattern.getValue());
requestPaint();
return;
}
else if (prop == &FileGeomPattern) {
if (prop == &FileGeomPattern) {
replacePatIncluded(FileGeomPattern.getValue());
makeLineSets();
requestPaint();
return;
}
else if (prop == &NameGeomPattern) {
if (prop == &NameGeomPattern) {
makeLineSets();
requestPaint();
return;
}
else if (prop == &BaseView) {
if (prop == &BaseView) {
// if the BaseView is a Section, then the option of using UsePreviousCut is
// valid.
if (BaseView.getValue() && BaseView.getValue()->isDerivedFrom<TechDraw::DrawViewSection>()) {
@@ -335,17 +346,17 @@ void DrawViewSection::onChanged(const App::Property* prop)
else {
UsePreviousCut.setStatus(App::Property::ReadOnly, true);
}
} else if (prop == &SectionLineStretch) {
}
if (prop == &SectionLineStretch) {
BaseView.getValue()->touch();
}
DrawView::onChanged(prop);
DrawView::onChanged(prop); //NOLINT
}
TopoDS_Shape DrawViewSection::getShapeToCut()
{
// Base::Console().Message("DVS::getShapeToCut() - %s\n",
// getNameInDocument());
App::DocumentObject* base = BaseView.getValue();
TechDraw::DrawViewPart* dvp = nullptr;
TechDraw::DrawViewSection* dvs = nullptr;
@@ -368,9 +379,11 @@ TopoDS_Shape DrawViewSection::getShapeToCut()
}
else if (base->isDerivedFrom<TechDraw::DrawViewPart>()) {
dvp = static_cast<TechDraw::DrawViewPart*>(base);
shapeToCut = dvp->getSourceShape();
constexpr bool fuseBefore{true};
constexpr bool allow2d{false};
shapeToCut = dvp->getSourceShape(!fuseBefore, allow2d);
if (FuseBeforeCut.getValue()) {
shapeToCut = dvp->getSourceShape(true);
shapeToCut = dvp->getSourceShape(fuseBefore);
}
}
else {
@@ -387,7 +400,6 @@ TopoDS_Shape DrawViewSection::getShapeForDetail() const
App::DocumentObjectExecReturn* DrawViewSection::execute()
{
// Base::Console().Message("DVS::execute() - %s\n", Label.getValue());
if (!keepUpdated()) {
return App::DocumentObject::StdReturn;
}
@@ -993,29 +1005,27 @@ ChangePointVector DrawViewSection::getChangePointsFromSectionLine()
// this should really be in BoundBox.h
//! check if point is in box or on boundary of box
//! compare to isInBox which doesn't allow on boundary
bool DrawViewSection::isReallyInBox(const Base::Vector3d v, const Base::BoundBox3d bb) const
bool DrawViewSection::isReallyInBox(const Base::Vector3d vec, const Base::BoundBox3d bb) const
{
if (v.x <= bb.MinX || v.x >= bb.MaxX) {
if (vec.x <= bb.MinX || vec.x >= bb.MaxX) {
return false;
}
if (v.y <= bb.MinY || v.y >= bb.MaxY) {
if (vec.y <= bb.MinY || vec.y >= bb.MaxY) {
return false;
}
if (v.z <= bb.MinZ || v.z >= bb.MaxZ) {
if (vec.z <= bb.MinZ || vec.z >= bb.MaxZ) {
return false;
}
return true;
}
bool DrawViewSection::isReallyInBox(const gp_Pnt p, const Bnd_Box& bb) const
bool DrawViewSection::isReallyInBox(const gp_Pnt& point, const Bnd_Box& bb) const
{
return !bb.IsOut(p);
return !bb.IsOut(point);
}
Base::Vector3d DrawViewSection::getXDirection() const
{
// Base::Console().Message("DVS::getXDirection() - %s\n",
// Label.getValue());
App::Property* prop = getPropertyByName("XDirection");
if (!prop) {
// No XDirection property. can this happen?
@@ -1038,7 +1048,7 @@ Base::Vector3d DrawViewSection::getXDirection() const
return XDirection.getValue();
}
void DrawViewSection::setCSFromBase(const std::string sectionName)
void DrawViewSection::setCSFromBase(const std::string& sectionName)
{
// Base::Console().Message("DVS::setCSFromBase(%s)\n",
// sectionName.c_str());
@@ -1052,10 +1062,8 @@ void DrawViewSection::setCSFromBase(const std::string sectionName)
}
// set the section CS based on an XY vector in BaseViews CS
void DrawViewSection::setCSFromBase(const Base::Vector3d localUnit)
void DrawViewSection::setCSFromBase(const Base::Vector3d& localUnit)
{
// Base::Console().Message("DVS::setCSFromBase(%s)\n",
// DrawUtil::formatVector(localUnit).c_str());
gp_Ax2 newSectionCS = getBaseDVP()->localVectorToCS(localUnit);
Base::Vector3d vDir(newSectionCS.Direction().X(),
@@ -1070,10 +1078,8 @@ void DrawViewSection::setCSFromBase(const Base::Vector3d localUnit)
}
// reset the section CS based on an XY vector in current section CS
void DrawViewSection::setCSFromLocalUnit(const Base::Vector3d localUnit)
void DrawViewSection::setCSFromLocalUnit(const Base::Vector3d& localUnit)
{
// Base::Console().Message("DVS::setCSFromLocalUnit(%s)\n",
// DrawUtil::formatVector(localUnit).c_str());
gp_Dir verticalDir = getSectionCS().YDirection();
gp_Ax1 verticalAxis(Base::convertTo<gp_Pnt>(SectionOrigin.getValue()), verticalDir);
gp_Dir oldNormal = getSectionCS().Direction();
@@ -1084,10 +1090,8 @@ void DrawViewSection::setCSFromLocalUnit(const Base::Vector3d localUnit)
XDirection.setValue(Base::convertTo<Base::Vector3d>(newCS.XDirection()));
}
gp_Ax2 DrawViewSection::getCSFromBase(const std::string sectionName) const
gp_Ax2 DrawViewSection::getCSFromBase(const std::string& sectionName) const
{
// Base::Console().Message("DVS::getCSFromBase(%s)\n",
// sectionName.c_str());
Base::Vector3d origin(0.0, 0.0, 0.0);
Base::Vector3d sectOrigin = SectionOrigin.getValue();
@@ -1143,7 +1147,6 @@ gp_Ax2 DrawViewSection::getCSFromBase(const std::string sectionName) const
// returns current section cs
gp_Ax2 DrawViewSection::getSectionCS() const
{
// Base::Console().Message("DVS::getSectionCS()\n");
Base::Vector3d vNormal = SectionNormal.getValue();
gp_Dir gNormal(vNormal.x, vNormal.y, vNormal.z);
Base::Vector3d vXDir = getXDirection();
@@ -1172,7 +1175,6 @@ Base::Vector3d DrawViewSection::getCutCentroid() const
std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
{
// Base::Console().Message("DVS::getDrawableLines(%d) - lineSets: %d\n", i, m_lineSets.size());
if (m_lineSets.empty()) {
makeLineSets();
}
@@ -1260,12 +1262,38 @@ void DrawViewSection::handleChangedPropertyType(Base::XMLReader &reader, const c
}
}
// checks that SectionNormal and XDirection are perpendicular and that Direction is the same as
// SectionNormal
bool DrawViewSection::checkSectionCS() const
{
auto vNormal = SectionNormal.getValue();
vNormal.Normalize();
auto vXDirection = XDirection.getValue();
vXDirection.Normalize();
auto vDirection = Direction.getValue();
if (vNormal.Length() == 0 ||
vXDirection.Length() == 0 ||
vDirection.Length() == 0) {
return false;
}
if (!vNormal.IsEqual(vDirection, EWTOLERANCE)) {
return false;
}
auto orthoDot = std::fabs(vNormal.Dot(vXDirection));
if (orthoDot > EWTOLERANCE) {
return false;
}
return true;
}
// hatch file routines
// create geometric hatch lines
void DrawViewSection::makeLineSets(void)
{
// Base::Console().Message("DVS::makeLineSets()\n");
if (PatIncluded.isEmpty()) {
return;
}
@@ -1289,8 +1317,6 @@ void DrawViewSection::makeLineSets(void)
void DrawViewSection::replaceSvgIncluded(std::string newSvgFile)
{
// Base::Console().Message("DVS::replaceSvgIncluded(%s)\n",
// newSvgFile.c_str());
if (newSvgFile.empty()) {
return;
}
@@ -1306,7 +1332,6 @@ void DrawViewSection::replaceSvgIncluded(std::string newSvgFile)
void DrawViewSection::replacePatIncluded(std::string newPatFile)
{
// Base::Console().Message("DVS::replacePatIncluded(%s)\n", newPatFile.c_str());
if (newPatFile.empty()) {
return;
}
@@ -1324,7 +1349,6 @@ void DrawViewSection::replacePatIncluded(std::string newPatFile)
void DrawViewSection::getParameters()
{
// Base::Console().Message("DVS::getParameters()\n");
bool fuseFirst = Preferences::getPreferenceGroup("General")->GetBool("SectionFuseFirst", false);
FuseBeforeCut.setValue(fuseFirst);
}
@@ -1336,8 +1360,6 @@ bool DrawViewSection::debugSection(void) const
int DrawViewSection::prefCutSurface(void) const
{
// Base::Console().Message("DVS::prefCutSurface()\n");
return Preferences::getPreferenceGroup("Decorations")
->GetInt("CutSurfaceDisplay", 2);// default to SvgHatch
}

View File

@@ -75,14 +75,17 @@ private:
using ChangePointVector = std::vector<ChangePoint>;
//NOLINTBEGIN
class TechDrawExport DrawViewSection: public DrawViewPart
{
PROPERTY_HEADER_WITH_OVERRIDE(TechDraw::DrawViewSection);
//NOLINTEND
public:
DrawViewSection();
~DrawViewSection() override;
//NOLINTBEGIN
App::PropertyLink BaseView;
App::PropertyDirection SectionNormal;
App::PropertyPosition SectionOrigin;
@@ -105,10 +108,10 @@ public:
App::PropertyBool UsePreviousCut; // new v022
App::PropertyFloatConstraint SectionLineStretch; // new v022
//NOLINTEND
bool isReallyInBox(const Base::Vector3d v, const Base::BoundBox3d bb) const;
bool isReallyInBox(const gp_Pnt p, const Bnd_Box& bb) const;
bool isReallyInBox(const Base::Vector3d vec, const Base::BoundBox3d bb) const;
bool isReallyInBox(const gp_Pnt& point, const Bnd_Box& bb) const;
App::DocumentObjectExecReturn* execute() override;
void onChanged(const App::Property* prop) override;
@@ -123,10 +126,10 @@ public:
void sectionExec(TopoDS_Shape& s);
virtual void makeSectionCut(const TopoDS_Shape& baseShape);
void postHlrTasks(void) override;
void postHlrTasks() override;
virtual void postSectionCutTasks();
void waitingForCut(bool s) { m_waitingForCut = s; }
bool waitingForCut(void) const { return m_waitingForCut; }
bool waitingForCut() const { return m_waitingForCut; }
bool waitingForResult() const override;
virtual TopoDS_Shape makeCuttingTool(double shapeSize);
@@ -136,10 +139,10 @@ public:
virtual TopoDS_Shape getShapeToPrepare() const { return m_cutPieces; }
//CS related methods
void setCSFromBase(const std::string sectionName);
void setCSFromBase(Base::Vector3d localUnit);
void setCSFromLocalUnit(const Base::Vector3d localUnit);
virtual gp_Ax2 getCSFromBase(const std::string sectionName) const;
void setCSFromBase(const std::string& sectionName);
void setCSFromBase(const Base::Vector3d& localUnit);
void setCSFromLocalUnit(const Base::Vector3d& localUnit);
virtual gp_Ax2 getCSFromBase(const std::string& sectionName) const;
gp_Ax2 getSectionCS() const;
Base::Vector3d getXDirection() const override;//don't use XDirection.getValue()
@@ -153,7 +156,7 @@ public:
virtual std::vector<TechDraw::FacePtr> makeTDSectionFaces(TopoDS_Compound topoDSFaces);
virtual TopoDS_Shape getShapeToIntersect() { return m_cutPieces; }
void makeLineSets(void);
void makeLineSets();
std::vector<LineSet> getDrawableLines(int i = 0);
std::vector<PATLineSpec> getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern);
@@ -169,14 +172,15 @@ public:
Base::Vector3d getSectionDirectionOnBaseView();
virtual ChangePointVector getChangePointsFromSectionLine();
bool showSectionEdges(void);
bool showSectionEdges();
TopoDS_Shape makeFaceFromWires(std::vector<TopoDS_Wire> &inWires);
Base::Vector3d getCutCentroid() const;
bool checkSectionCS() const;
public Q_SLOTS:
virtual void onSectionCutFinished(void);
virtual void onSectionCutFinished();
protected:
TopoDS_Compound m_sectionTopoDSFaces;//needed for hatching