[TD]move makeAlignedPieces to separate thread
- correct ComplexSection rotation - fix fail to load CS for some profiles and directions
This commit is contained in:
@@ -81,6 +81,9 @@
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QtConcurrentRun>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
@@ -129,12 +132,12 @@ using DU = DrawUtil;
|
||||
|
||||
PROPERTY_SOURCE(TechDraw::DrawComplexSection, TechDraw::DrawViewSection)
|
||||
|
||||
const char *DrawComplexSection::ProjectionStrategyEnums[] = {"Offset", "Aligned", "NoParallel",
|
||||
const char* DrawComplexSection::ProjectionStrategyEnums[] = {"Offset", "Aligned", "NoParallel",
|
||||
nullptr};
|
||||
|
||||
DrawComplexSection::DrawComplexSection()
|
||||
{
|
||||
static const char *fgroup = "Cutting Tool";
|
||||
static const char* fgroup = "Cutting Tool";
|
||||
|
||||
ADD_PROPERTY_TYPE(CuttingToolWireObject, (nullptr), fgroup, App::Prop_None,
|
||||
"A sketch that describes the cutting tool");
|
||||
@@ -147,7 +150,7 @@ DrawComplexSection::DrawComplexSection()
|
||||
TopoDS_Shape DrawComplexSection::getShapeToCut()
|
||||
{
|
||||
// Base::Console().Message("DCS::getShapeToCut()\n");
|
||||
App::DocumentObject *base = BaseView.getValue();
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
TopoDS_Shape shapeToCut;
|
||||
if (base && base == this) {
|
||||
shapeToCut = getSourceShape();
|
||||
@@ -172,7 +175,7 @@ TopoDS_Shape DrawComplexSection::getShapeToCut()
|
||||
|
||||
TopoDS_Shape DrawComplexSection::makeCuttingTool(double dMax)
|
||||
{
|
||||
// Base::Console().Message("DCS::makeCuttingTool()\n");
|
||||
// Base::Console().Message("DCS::makeCuttingTool()\n");
|
||||
TopoDS_Wire profileWire = makeProfileWire();
|
||||
if (profileWire.IsNull()) {
|
||||
throw Base::RuntimeError("Can not make wire from cutting tool (1)");
|
||||
@@ -244,6 +247,7 @@ TopoDS_Shape DrawComplexSection::makeCuttingTool(double dMax)
|
||||
|
||||
TopoDS_Shape DrawComplexSection::getShapeToPrepare() const
|
||||
{
|
||||
// Base::Console().Message("DCS::getShapeToPrepare()\n");
|
||||
if (ProjectionStrategy.getValue() == 0) {
|
||||
//Offset. Use regular section behaviour
|
||||
return DrawViewSection::getShapeToPrepare();
|
||||
@@ -253,49 +257,84 @@ TopoDS_Shape DrawComplexSection::getShapeToPrepare() const
|
||||
}
|
||||
|
||||
//get the shape ready for projection and cut surface finding
|
||||
TopoDS_Shape DrawComplexSection::prepareShape(const TopoDS_Shape &cutShape, double shapeSize)
|
||||
TopoDS_Shape DrawComplexSection::prepareShape(const TopoDS_Shape& cutShape, double shapeSize)
|
||||
{
|
||||
// Base::Console().Message("DCS::prepareShape() - strategy: %d\n", ProjectionStrategy.getValue());
|
||||
// Base::Console().Message("DCS::prepareShape() - strategy: %d\n", ProjectionStrategy.getValue());
|
||||
if (ProjectionStrategy.getValue() == 0) {
|
||||
//Offset. Use regular section behaviour
|
||||
return DrawViewSection::prepareShape(cutShape, shapeSize);
|
||||
}
|
||||
|
||||
//"Aligned" projection (Aligned Section)
|
||||
TopoDS_Shape alignedResult;
|
||||
try {
|
||||
alignedResult = makeAlignedPieces(cutShape, m_toolFaceShape, shapeSize);
|
||||
}
|
||||
catch (Base::RuntimeError& e) {
|
||||
Base::Console().Error("Complex Section - %s\n", e.what());
|
||||
if (m_alignResult.IsNull()) {
|
||||
return TopoDS_Shape();
|
||||
}
|
||||
|
||||
if (alignedResult.IsNull()) {
|
||||
return TopoDS_Shape();
|
||||
}
|
||||
|
||||
TopoDS_Shape preparedShape = scaleShape(alignedResult, getScale());
|
||||
TopoDS_Shape preparedShape = scaleShape(m_alignResult, getScale());
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(), 0.0)) {
|
||||
preparedShape = TechDraw::rotateShape(preparedShape,
|
||||
getProjectionCS(),
|
||||
Rotation.getValue());
|
||||
preparedShape =
|
||||
TechDraw::rotateShape(preparedShape, getProjectionCS(), Rotation.getValue());
|
||||
}
|
||||
|
||||
return preparedShape;
|
||||
}
|
||||
|
||||
|
||||
void DrawComplexSection::makeSectionCut(TopoDS_Shape& baseShape)
|
||||
{
|
||||
// Base::Console().Message("DCS::makeSectionCut() - %s - baseShape.IsNull: %d\n",
|
||||
// getNameInDocument(), baseShape.IsNull());
|
||||
if (ProjectionStrategy.getValue() == 0) {
|
||||
//Offset. Use regular section behaviour
|
||||
return DrawViewSection::makeSectionCut(baseShape);
|
||||
}
|
||||
|
||||
try {
|
||||
connectAlignWatcher =
|
||||
QObject::connect(&m_alignWatcher, &QFutureWatcherBase::finished, &m_alignWatcher,
|
||||
[this] { this->onSectionCutFinished(); });
|
||||
m_alignFuture = QtConcurrent::run(this, &DrawComplexSection::makeAlignedPieces, baseShape);
|
||||
m_alignWatcher.setFuture(m_alignFuture);
|
||||
waitingForAlign(true);
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Message("DCS::makeSectionCut - failed to make alignedPieces");
|
||||
return;
|
||||
}
|
||||
|
||||
return DrawViewSection::makeSectionCut(baseShape);
|
||||
}
|
||||
|
||||
|
||||
void DrawComplexSection::onSectionCutFinished()
|
||||
{
|
||||
// Base::Console().Message("DCS::onSectionCutFinished() - %s - cut: %d align: %d\n",
|
||||
// getNameInDocument(), m_cutFuture.isRunning(), m_alignFuture.isRunning());
|
||||
if (m_cutFuture.isRunning() || //waitingForCut()
|
||||
m_alignFuture.isRunning()) {//waitingForAlign()
|
||||
//can not continue yet. return until the other thread ends
|
||||
return;
|
||||
}
|
||||
|
||||
DrawViewSection::onSectionCutFinished();
|
||||
|
||||
QObject::disconnect(connectAlignWatcher);
|
||||
}
|
||||
|
||||
//for Aligned strategy, cut the rawShape by each segment of the tool
|
||||
//TODO: this process should replace the "makeSectionCut" from DVS
|
||||
TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
const TopoDS_Shape &toolFaceShape,
|
||||
double extrudeDistance)
|
||||
void DrawComplexSection::makeAlignedPieces(const TopoDS_Shape& rawShape)
|
||||
{
|
||||
// Base::Console().Message("DCS::makeAlignedPieces()\n");
|
||||
// Base::Console().Message("DCS::makeAlignedPieces() - rawShape.isNull: %d\n", rawShape.IsNull());
|
||||
|
||||
if (!canBuild(getSectionCS(), CuttingToolWireObject.getValue())) {
|
||||
throw Base::RuntimeError("Profile is parallel to Section Normal");
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Shape> pieces;
|
||||
std::vector<double> pieceXSizeAll; //size in sectionCS.XDirection (width)
|
||||
std::vector<double> pieceYSizeAll; //size in sectionCS.Direction (depth)
|
||||
std::vector<double> pieceZSizeAll; //size in sectionCS.YDirection (height)
|
||||
std::vector<double> pieceXSizeAll;//size in sectionCS.XDirection (width)
|
||||
std::vector<double> pieceYSizeAll;//size in sectionCS.Direction (depth)
|
||||
std::vector<double> pieceZSizeAll;//size in sectionCS.YDirection (height)
|
||||
|
||||
//make a CS from the section CS ZX plane to allow piece positioning (left-right)
|
||||
//with the section view vertical centerline and (in-out, forward-backward) with
|
||||
@@ -312,12 +351,12 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
throw Base::RuntimeError("Can not make wire from cutting tool (2)");
|
||||
}
|
||||
gp_Vec gProfileVec = makeProfileVector(profileWire);
|
||||
//now we want to know what the profileVector looks like on the page (only X,Y coords)
|
||||
gProfileVec = projectVector(gProfileVec).Normalized();
|
||||
gp_Vec rotateAxis = (getSectionCS().Direction()).Crossed(gProfileVec);
|
||||
|
||||
if (!canBuild(getSectionCS(), CuttingToolWireObject.getValue())) {
|
||||
throw Base::RuntimeError("Profile is parallel to Section Normal");
|
||||
}
|
||||
//now we want to know what the profileVector looks like on the page (only X,Y coords)
|
||||
//so we know if we are going to stack views vertically or horizontally and if the segments
|
||||
//will occur (left to right or right to left) or (top to bottom or bottom to top)
|
||||
gProfileVec = projectVector(gProfileVec).Normalized();
|
||||
|
||||
bool isProfileVertical = true;
|
||||
if (fabs(gProfileVec.Dot(gp::OY().Direction().XYZ())) != 1.0) {
|
||||
@@ -337,11 +376,9 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
verticalReverser = -1.0;
|
||||
}
|
||||
|
||||
gp_Vec rotateAxis = getSectionCS().Direction().Crossed(gProfileVec);
|
||||
|
||||
//make a tool for each segment of the toolFaceShape and intersect it with the
|
||||
//raw shape
|
||||
TopExp_Explorer expFaces(toolFaceShape, TopAbs_FACE);
|
||||
TopExp_Explorer expFaces(m_toolFaceShape, TopAbs_FACE);
|
||||
for (int iPiece = 0; expFaces.More(); expFaces.Next(), iPiece++) {
|
||||
TopoDS_Face face = TopoDS::Face(expFaces.Current());
|
||||
gp_Vec segmentNormal = gp_Vec(getFaceNormal(face));
|
||||
@@ -350,12 +387,12 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
continue;
|
||||
}
|
||||
//we only want to reverse the segment normal if it is not perpendicular to section normal
|
||||
if (segmentNormal.Dot(-gProjectionUnit) != 0.0
|
||||
if (segmentNormal.Dot(gProjectionUnit) != 0.0
|
||||
&& segmentNormal.Angle(gProjectionUnit) <= M_PI_2) {
|
||||
segmentNormal.Reverse();
|
||||
}
|
||||
|
||||
gp_Vec extrudeDir = segmentNormal * extrudeDistance;
|
||||
gp_Vec extrudeDir = segmentNormal * m_shapeSize;
|
||||
BRepPrimAPI_MakePrism mkPrism(face, extrudeDir);
|
||||
TopoDS_Shape segmentTool = mkPrism.Shape();
|
||||
TopoDS_Shape intersect = shapeShapeIntersect(segmentTool, rawShape);
|
||||
@@ -410,7 +447,8 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
gp_Vec netDisplacement = -1.0 * gp_Vec(findCentroid(pieceAligned).XYZ()) + yVector;
|
||||
//if we are going to space along X, we need to bring the pieces back into alignment
|
||||
//with the XY plane. If we are stacking the pieces along Z, we don't want a vertical adjustment.
|
||||
gp_Vec xyDisplacement = isProfileVertical ? gp_Vec(0.0, 0.0, 0.0) : gp_Vec(gp::OZ().Direction());
|
||||
gp_Vec xyDisplacement =
|
||||
isProfileVertical ? gp_Vec(0.0, 0.0, 0.0) : gp_Vec(gp::OZ().Direction());
|
||||
double dot = gp_Vec(gp::OZ().Direction()).Dot(alignedCS.Direction());
|
||||
xyDisplacement = xyDisplacement * dot * (pieceZSize / 2.0);
|
||||
netDisplacement = netDisplacement + xyDisplacement;
|
||||
@@ -425,19 +463,22 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
}
|
||||
|
||||
if (pieces.empty()) {
|
||||
return TopoDS_Compound();
|
||||
m_alignResult = TopoDS_Compound();
|
||||
return;
|
||||
}
|
||||
|
||||
int pieceCount = pieces.size();
|
||||
if (pieceCount < 2) {
|
||||
//no need to space out the pieces
|
||||
return TopoDS::Compound(pieces.front());
|
||||
m_alignResult = TopoDS::Compound(pieces.front());
|
||||
return;
|
||||
}
|
||||
|
||||
//space the pieces "horizontally" (stdX) or "vertically" (stdZ)
|
||||
double movementReverser = isProfileVertical ? verticalReverser : horizReverser;
|
||||
//TODO: non-cardinal profiles!
|
||||
gp_Vec movementAxis = isProfileVertical ? gp_Vec(gp::OZ().Direction()) : gp_Vec(gp::OX().Direction());
|
||||
gp_Vec movementAxis =
|
||||
isProfileVertical ? gp_Vec(gp::OZ().Direction()) : gp_Vec(gp::OX().Direction());
|
||||
gp_Vec gMovementVector = movementAxis * movementReverser;
|
||||
|
||||
int stopAt = pieces.size();
|
||||
@@ -459,7 +500,7 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound comp;
|
||||
builder.MakeCompound(comp);
|
||||
for (auto &piece : pieces) {
|
||||
for (auto& piece : pieces) {
|
||||
builder.Add(comp, piece);
|
||||
}
|
||||
|
||||
@@ -480,7 +521,7 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
BRepTools::Write(alignedCompound, "DCSmap50AlignedCompound.brep");//debug
|
||||
}
|
||||
|
||||
return alignedCompound;
|
||||
m_alignResult = alignedCompound;
|
||||
}
|
||||
|
||||
//! tries to find the intersection faces of the cut shape and the cutting tool.
|
||||
@@ -488,9 +529,9 @@ TopoDS_Shape DrawComplexSection::makeAlignedPieces(const TopoDS_Shape &rawShape,
|
||||
//! case is a compound of individual cuts) with the "effective" (flattened) section plane.
|
||||
//! Profiles containing curves need special handling.
|
||||
TopoDS_Compound
|
||||
DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape &shapeToIntersect)
|
||||
DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape& shapeToIntersect)
|
||||
{
|
||||
// Base::Console().Message("DCS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
|
||||
// Base::Console().Message("DCS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
|
||||
if (shapeToIntersect.IsNull()) {
|
||||
// this shouldn't happen
|
||||
Base::Console().Warning("DCS::findSectionPlaneInter - %s - cut shape is Null\n",
|
||||
@@ -505,10 +546,10 @@ DrawComplexSection::findSectionPlaneIntersections(const TopoDS_Shape &shapeToInt
|
||||
}
|
||||
|
||||
//Intersect cutShape with each segment of the cutting tool
|
||||
TopoDS_Compound DrawComplexSection::singleToolIntersections(const TopoDS_Shape &cutShape)
|
||||
TopoDS_Compound DrawComplexSection::singleToolIntersections(const TopoDS_Shape& cutShape)
|
||||
{
|
||||
// Base::Console().Message("DCS::singleToolInterSections()\n");
|
||||
App::DocumentObject *toolObj = CuttingToolWireObject.getValue();
|
||||
App::DocumentObject* toolObj = CuttingToolWireObject.getValue();
|
||||
if (!isLinearProfile(toolObj)) {
|
||||
//TODO: special handling here
|
||||
// Base::Console().Message("DCS::singleToolIntersection - profile has curves\n");
|
||||
@@ -534,20 +575,22 @@ TopoDS_Compound DrawComplexSection::singleToolIntersections(const TopoDS_Shape &
|
||||
continue;
|
||||
}
|
||||
std::vector<TopoDS_Face> commonFaces = faceShapeIntersect(face, m_toolFaceShape);
|
||||
for (auto &cFace : commonFaces) { builder.Add(result, cFace); }
|
||||
for (auto& cFace : commonFaces) {
|
||||
builder.Add(result, cFace);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//Intersect cutShape with the effective (flattened) cutting plane to generate cut surface faces
|
||||
TopoDS_Compound DrawComplexSection::alignedToolIntersections(const TopoDS_Shape &cutShape)
|
||||
TopoDS_Compound DrawComplexSection::alignedToolIntersections(const TopoDS_Shape& cutShape)
|
||||
{
|
||||
// Base::Console().Message("DCS::alignedToolIntersections()\n");
|
||||
// Base::Console().Message("DCS::alignedToolIntersections()\n");
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound result;
|
||||
builder.MakeCompound(result);
|
||||
|
||||
App::DocumentObject *toolObj = CuttingToolWireObject.getValue();
|
||||
App::DocumentObject* toolObj = CuttingToolWireObject.getValue();
|
||||
if (!isLinearProfile(toolObj)) {
|
||||
//TODO: special handling here
|
||||
// Base::Console().Message("DCS::alignedToolIntersection - profile has curves\n");
|
||||
@@ -567,7 +610,9 @@ TopoDS_Compound DrawComplexSection::alignedToolIntersections(const TopoDS_Shape
|
||||
continue;
|
||||
}
|
||||
std::vector<TopoDS_Face> commonFaces = faceShapeIntersect(face, cuttingFace);
|
||||
for (auto &cFace : commonFaces) { builder.Add(result, cFace); }
|
||||
for (auto& cFace : commonFaces) {
|
||||
builder.Add(result, cFace);
|
||||
}
|
||||
}
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(cuttingFace, "DCSAlignedCuttingFace.brep"); //debug
|
||||
@@ -579,7 +624,7 @@ TopoDS_Compound DrawComplexSection::alignedToolIntersections(const TopoDS_Shape
|
||||
|
||||
TopoDS_Compound DrawComplexSection::alignSectionFaces(TopoDS_Shape faceIntersections)
|
||||
{
|
||||
// Base::Console().Message("DCS::alignSectionFaces() - faceIntersections.null: %d\n", faceIntersections.IsNull());
|
||||
// Base::Console().Message("DCS::alignSectionFaces() - faceIntersections.null: %d\n", faceIntersections.IsNull());
|
||||
if (ProjectionStrategy.getValue() == 0) {
|
||||
//Offset. Use regular section behaviour
|
||||
return DrawViewSection::alignSectionFaces(faceIntersections);
|
||||
@@ -598,13 +643,13 @@ TopoDS_Shape DrawComplexSection::getShapeToIntersect()
|
||||
}
|
||||
TopoDS_Wire DrawComplexSection::makeProfileWire() const
|
||||
{
|
||||
App::DocumentObject *toolObj = CuttingToolWireObject.getValue();
|
||||
App::DocumentObject* toolObj = CuttingToolWireObject.getValue();
|
||||
return makeProfileWire(toolObj);
|
||||
}
|
||||
|
||||
TopoDS_Wire DrawComplexSection::makeProfileWire(App::DocumentObject *toolObj)
|
||||
TopoDS_Wire DrawComplexSection::makeProfileWire(App::DocumentObject* toolObj)
|
||||
{
|
||||
// Base::Console().Message("DCS::makeProfileWire()\n");
|
||||
// Base::Console().Message("DCS::makeProfileWire()\n");
|
||||
if (!isProfileObject(toolObj)) {
|
||||
return TopoDS_Wire();
|
||||
}
|
||||
@@ -642,7 +687,7 @@ BaseGeomPtrVector DrawComplexSection::makeSectionLineGeometry()
|
||||
{
|
||||
// Base::Console().Message("DCS::makeSectionLineGeometry()\n");
|
||||
BaseGeomPtrVector result;
|
||||
DrawViewPart *baseDvp = dynamic_cast<DrawViewPart *>(BaseView.getValue());
|
||||
DrawViewPart* baseDvp = dynamic_cast<DrawViewPart*>(BaseView.getValue());
|
||||
if (baseDvp) {
|
||||
TopoDS_Wire lineWire = makeSectionLineWire();
|
||||
TopoDS_Shape projectedWire =
|
||||
@@ -673,7 +718,7 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawComplexSection::sectionLineEnds()
|
||||
Base::Vector3d first = Base::Vector3d(gpFirst.X(), gpFirst.Y(), gpFirst.Z());
|
||||
Base::Vector3d last = Base::Vector3d(gpLast.X(), gpLast.Y(), gpLast.Z());
|
||||
|
||||
DrawViewPart *baseDvp = dynamic_cast<DrawViewPart *>(BaseView.getValue());
|
||||
DrawViewPart* baseDvp = dynamic_cast<DrawViewPart*>(BaseView.getValue());
|
||||
if (baseDvp) {
|
||||
first = baseDvp->projectPoint(first);
|
||||
last = baseDvp->projectPoint(last);
|
||||
@@ -688,7 +733,7 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawComplexSection::sectionArrowDirs()
|
||||
{
|
||||
// Base::Console().Message("DCS::sectionArrowDirs()\n");
|
||||
std::pair<Base::Vector3d, Base::Vector3d> result;
|
||||
App::DocumentObject *toolObj = CuttingToolWireObject.getValue();
|
||||
App::DocumentObject* toolObj = CuttingToolWireObject.getValue();
|
||||
TopoDS_Wire profileWire = makeProfileWire(toolObj);
|
||||
if (profileWire.IsNull()) {
|
||||
return result;
|
||||
@@ -707,7 +752,9 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawComplexSection::sectionArrowDirs()
|
||||
|
||||
std::vector<TopoDS_Face> faces;
|
||||
TopExp_Explorer expl(toolFaceShape, TopAbs_FACE);
|
||||
for (; expl.More(); expl.Next()) { faces.push_back(TopoDS::Face(expl.Current())); }
|
||||
for (; expl.More(); expl.Next()) {
|
||||
faces.push_back(TopoDS::Face(expl.Current()));
|
||||
}
|
||||
|
||||
gp_Vec gDir0 = gp_Vec(getFaceNormal(faces.front()));
|
||||
gp_Vec gDir1 = gp_Vec(getFaceNormal(faces.back()));
|
||||
@@ -727,7 +774,7 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawComplexSection::sectionArrowDirs()
|
||||
Base::Vector3d vDir1 = DU::toVector3d(gDir1);
|
||||
vDir0.Normalize();
|
||||
vDir1.Normalize();
|
||||
DrawViewPart *baseDvp = dynamic_cast<DrawViewPart *>(BaseView.getValue());
|
||||
DrawViewPart* baseDvp = dynamic_cast<DrawViewPart*>(BaseView.getValue());
|
||||
if (baseDvp) {
|
||||
vDir0 = baseDvp->projectPoint(vDir0, true);
|
||||
vDir1 = baseDvp->projectPoint(vDir1, true);
|
||||
@@ -742,8 +789,8 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawComplexSection::sectionArrowDirs()
|
||||
TopoDS_Wire DrawComplexSection::makeSectionLineWire()
|
||||
{
|
||||
TopoDS_Wire lineWire;
|
||||
App::DocumentObject *toolObj = CuttingToolWireObject.getValue();
|
||||
DrawViewPart *baseDvp = dynamic_cast<DrawViewPart *>(BaseView.getValue());
|
||||
App::DocumentObject* toolObj = CuttingToolWireObject.getValue();
|
||||
DrawViewPart* baseDvp = dynamic_cast<DrawViewPart*>(BaseView.getValue());
|
||||
if (baseDvp) {
|
||||
Base::Vector3d centroid = baseDvp->getCurrentCentroid();
|
||||
TopoDS_Shape sTrans =
|
||||
@@ -775,7 +822,7 @@ ChangePointVector DrawComplexSection::getChangePointsFromSectionLine()
|
||||
// Base::Console().Message("DCS::getChangePointsFromSectionLine()\n");
|
||||
ChangePointVector result;
|
||||
std::vector<gp_Pnt> allPoints;
|
||||
DrawViewPart *baseDvp = dynamic_cast<DrawViewPart *>(BaseView.getValue());
|
||||
DrawViewPart* baseDvp = dynamic_cast<DrawViewPart*>(BaseView.getValue());
|
||||
if (baseDvp) {
|
||||
TopoDS_Wire lineWire = makeSectionLineWire();
|
||||
TopoDS_Shape projectedWire =
|
||||
@@ -825,7 +872,7 @@ ChangePointVector DrawComplexSection::getChangePointsFromSectionLine()
|
||||
gp_Ax2 DrawComplexSection::getCSFromBase(const std::string sectionName) const
|
||||
{
|
||||
// Base::Console().Message("DCS::getCSFromBase()\n");
|
||||
App::DocumentObject *base = BaseView.getValue();
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (!base
|
||||
|| !base->getTypeId().isDerivedFrom(
|
||||
TechDraw::DrawViewPart::getClassTypeId())) {//is second clause necessary?
|
||||
@@ -838,17 +885,18 @@ gp_Ax2 DrawComplexSection::getCSFromBase(const std::string sectionName) const
|
||||
//simple projection of a 3d vector onto the paper space
|
||||
gp_Vec DrawComplexSection::projectVector(const gp_Vec& vec) const
|
||||
{
|
||||
HLRAlgo_Projector projector( getProjectionCS() );
|
||||
HLRAlgo_Projector projector(getProjectionCS());
|
||||
gp_Pnt2d prjPnt;
|
||||
projector.Project(gp_Pnt(vec.XYZ()), prjPnt);
|
||||
return gp_Vec(prjPnt.X(), prjPnt.Y(), 0.0);
|
||||
}
|
||||
|
||||
//static
|
||||
//TODO: centralize all the projection routines scattered around the module!
|
||||
gp_Vec DrawComplexSection::projectVector(const gp_Vec& vec, gp_Ax2 sectionCS)
|
||||
{
|
||||
// Base::Console().Message("DCS::projectVector(%s, CS)\n", DU::formatVector(vec).c_str());
|
||||
HLRAlgo_Projector projector( sectionCS );
|
||||
// Base::Console().Message("DCS::projectVector(%s, CS)\n", DU::formatVector(vec).c_str());
|
||||
HLRAlgo_Projector projector(sectionCS);
|
||||
gp_Pnt2d prjPnt;
|
||||
projector.Project(gp_Pnt(vec.XYZ()), prjPnt);
|
||||
return gp_Vec(prjPnt.X(), prjPnt.Y(), 0.0);
|
||||
@@ -875,7 +923,7 @@ gp_Pln DrawComplexSection::getSectionPlane() const
|
||||
|
||||
bool DrawComplexSection::isBaseValid() const
|
||||
{
|
||||
App::DocumentObject *base = BaseView.getValue();
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (!base) {
|
||||
//complex section is not based on an existing DVP
|
||||
return true;
|
||||
@@ -893,7 +941,7 @@ bool DrawComplexSection::isBaseValid() const
|
||||
//the shape after extrusion. As long as the profile is within the extent of the shape in the
|
||||
//extrude direction we should be ok. the extrude direction has to be perpendicular to the profile and SectionNormal
|
||||
bool DrawComplexSection::validateProfilePosition(TopoDS_Wire profileWire, gp_Ax2 sectionCS,
|
||||
gp_Dir &gClosestBasis) const
|
||||
gp_Dir& gClosestBasis) const
|
||||
{
|
||||
// Base::Console().Message("DCS::validateProfilePosition()\n");
|
||||
gp_Vec gProfileVector = makeProfileVector(profileWire);
|
||||
@@ -965,9 +1013,9 @@ bool DrawComplexSection::canBuild(gp_Ax2 sectionCS, App::DocumentObject* profile
|
||||
return true;
|
||||
}
|
||||
gp_Vec gProfileVec = makeProfileVector(makeProfileWire(profileObject));
|
||||
gProfileVec = projectVector(gProfileVec, sectionCS).Normalized();
|
||||
// gProfileVec = projectVector(gProfileVec, sectionCS).Normalized();
|
||||
double dot = fabs(gProfileVec.Dot(sectionCS.Direction()));
|
||||
if ( DU::fpCompare(dot, 1.0, EWTOLERANCE)) {
|
||||
if (DU::fpCompare(dot, 1.0, EWTOLERANCE)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -977,7 +1025,7 @@ bool DrawComplexSection::canBuild(gp_Ax2 sectionCS, App::DocumentObject* profile
|
||||
|
||||
//make a "face" (not necessarily a TopoDS_Face since the extrusion of a wire is a shell)
|
||||
//from a single open wire by displacing the wire extruding it
|
||||
TopoDS_Shape DrawComplexSection::extrudeWireToFace(TopoDS_Wire &wire, gp_Dir extrudeDir,
|
||||
TopoDS_Shape DrawComplexSection::extrudeWireToFace(TopoDS_Wire& wire, gp_Dir extrudeDir,
|
||||
double extrudeDist)
|
||||
{
|
||||
gp_Trsf mov;
|
||||
@@ -992,7 +1040,7 @@ TopoDS_Shape DrawComplexSection::extrudeWireToFace(TopoDS_Wire &wire, gp_Dir ext
|
||||
|
||||
//returns the normal of the face to be extruded into a cutting tool
|
||||
//the face is expected to be planar
|
||||
gp_Dir DrawComplexSection::getFaceNormal(TopoDS_Face &face)
|
||||
gp_Dir DrawComplexSection::getFaceNormal(TopoDS_Face& face)
|
||||
{
|
||||
BRepAdaptor_Surface adapt(face);
|
||||
double uParmFirst = adapt.FirstUParameter();
|
||||
@@ -1010,7 +1058,7 @@ gp_Dir DrawComplexSection::getFaceNormal(TopoDS_Face &face)
|
||||
return normalDir;
|
||||
}
|
||||
|
||||
bool DrawComplexSection::boxesIntersect(TopoDS_Face &face, TopoDS_Shape &shape)
|
||||
bool DrawComplexSection::boxesIntersect(TopoDS_Face& face, TopoDS_Shape& shape)
|
||||
{
|
||||
Bnd_Box box0, box1;
|
||||
BRepBndLib::Add(face, box0);
|
||||
@@ -1023,8 +1071,8 @@ bool DrawComplexSection::boxesIntersect(TopoDS_Face &face, TopoDS_Shape &shape)
|
||||
return true;
|
||||
}
|
||||
|
||||
TopoDS_Shape DrawComplexSection::shapeShapeIntersect(const TopoDS_Shape &shape0,
|
||||
const TopoDS_Shape &shape1)
|
||||
TopoDS_Shape DrawComplexSection::shapeShapeIntersect(const TopoDS_Shape& shape0,
|
||||
const TopoDS_Shape& shape1)
|
||||
{
|
||||
BRepAlgoAPI_Common anOp;
|
||||
anOp.SetFuzzyValue(EWTOLERANCE);
|
||||
@@ -1042,8 +1090,8 @@ TopoDS_Shape DrawComplexSection::shapeShapeIntersect(const TopoDS_Shape &shape0,
|
||||
}
|
||||
|
||||
//find all the intersecting regions of face and shape
|
||||
std::vector<TopoDS_Face> DrawComplexSection::faceShapeIntersect(const TopoDS_Face &face,
|
||||
const TopoDS_Shape &shape)
|
||||
std::vector<TopoDS_Face> DrawComplexSection::faceShapeIntersect(const TopoDS_Face& face,
|
||||
const TopoDS_Shape& shape)
|
||||
{
|
||||
// Base::Console().Message("DCS::faceShapeIntersect()\n");
|
||||
TopoDS_Shape intersect = shapeShapeIntersect(face, shape);
|
||||
@@ -1081,12 +1129,14 @@ TopoDS_Wire DrawComplexSection::makeNoseToTailWire(TopoDS_Wire inWire)
|
||||
}
|
||||
|
||||
BRepBuilderAPI_MakeWire mkWire;
|
||||
for (auto &edge : sortedList) { mkWire.Add(edge); }
|
||||
for (auto& edge : sortedList) {
|
||||
mkWire.Add(edge);
|
||||
}
|
||||
return mkWire.Wire();
|
||||
}
|
||||
|
||||
//static
|
||||
bool DrawComplexSection::isProfileObject(App::DocumentObject *obj)
|
||||
bool DrawComplexSection::isProfileObject(App::DocumentObject* obj)
|
||||
{
|
||||
//if the object's shape is a wire or an edge, then it can be a profile object
|
||||
TopoDS_Shape shape = Part::Feature::getShape(obj);
|
||||
@@ -1100,7 +1150,7 @@ bool DrawComplexSection::isProfileObject(App::DocumentObject *obj)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DrawComplexSection::isMultiSegmentProfile(App::DocumentObject *obj)
|
||||
bool DrawComplexSection::isMultiSegmentProfile(App::DocumentObject* obj)
|
||||
{
|
||||
//if the object's shape is a wire or an edge, then it can be a profile object
|
||||
TopoDS_Shape shape = Part::Feature::getShape(obj);
|
||||
@@ -1129,7 +1179,7 @@ bool DrawComplexSection::isMultiSegmentProfile(App::DocumentObject *obj)
|
||||
}
|
||||
|
||||
//check if the profile has curves in it
|
||||
bool DrawComplexSection::isLinearProfile(App::DocumentObject *obj)
|
||||
bool DrawComplexSection::isLinearProfile(App::DocumentObject* obj)
|
||||
{
|
||||
TopoDS_Shape shape = Part::Feature::getShape(obj);
|
||||
if (shape.IsNull()) {
|
||||
@@ -1180,7 +1230,7 @@ namespace App
|
||||
{
|
||||
/// @cond DOXERR
|
||||
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawComplexSectionPython, TechDraw::DrawComplexSection)
|
||||
template<> const char *TechDraw::DrawComplexSectionPython::getViewProviderName() const
|
||||
template<> const char* TechDraw::DrawComplexSectionPython::getViewProviderName() const
|
||||
{
|
||||
return "TechDrawGui::ViewProviderDrawingView";
|
||||
}
|
||||
|
||||
@@ -58,13 +58,22 @@ public:
|
||||
TopoDS_Compound alignSectionFaces(TopoDS_Shape faceIntersections) override;
|
||||
std::pair<Base::Vector3d, Base::Vector3d> sectionLineEnds() override;
|
||||
|
||||
void makeSectionCut(TopoDS_Shape &baseShape) override;
|
||||
|
||||
void waitingForAlign(bool s) { m_waitingForAlign = s; }
|
||||
bool waitingForAlign(void) const { return m_waitingForAlign; }
|
||||
|
||||
|
||||
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);
|
||||
TopoDS_Shape extrudeWireToFace(TopoDS_Wire &wire, gp_Dir extrudeDir, double extrudeDist);
|
||||
TopoDS_Shape makeAlignedPieces(const TopoDS_Shape &rawShape, const TopoDS_Shape &toolFaceShape,
|
||||
double extrudeDistance);
|
||||
TopoDS_Shape distributeAlignedPieces(std::vector<TopoDS_Shape> pieces);
|
||||
// void makeAlignedPieces(const TopoDS_Shape &rawShape, const TopoDS_Shape &toolFaceShape,
|
||||
// double extrudeDistance);
|
||||
void makeAlignedPieces(const TopoDS_Shape &rawShape);
|
||||
TopoDS_Compound singleToolIntersections(const TopoDS_Shape &cutShape);
|
||||
TopoDS_Compound alignedToolIntersections(const TopoDS_Shape &cutShape);
|
||||
|
||||
@@ -94,6 +103,12 @@ private:
|
||||
gp_Dir getFaceNormal(TopoDS_Face &face);
|
||||
|
||||
TopoDS_Shape m_toolFaceShape;
|
||||
TopoDS_Shape m_alignResult;
|
||||
|
||||
QMetaObject::Connection connectAlignWatcher;
|
||||
QFutureWatcher<void> m_alignWatcher;
|
||||
QFuture<void> m_alignFuture;
|
||||
bool m_waitingForAlign;
|
||||
|
||||
static const char *ProjectionStrategyEnums[];
|
||||
};
|
||||
|
||||
@@ -193,6 +193,7 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
Base::Console().Warning("%s has no 3D References but is Type: True\n", getNameInDocument());
|
||||
MeasureType.setValue("Projected");
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (prop == &References3D) { //have to rebuild the Measurement object
|
||||
// Base::Console().Message("DVD::onChanged - References3D\n");
|
||||
@@ -202,6 +203,7 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
} else if (MeasureType.isValue("True")) { //empty 3dRefs, but True
|
||||
MeasureType.touch(); //run MeasureType logic for this case
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (prop == &Type) { //why??
|
||||
FormatSpec.setValue(getDefaultFormatSpec().c_str());
|
||||
@@ -215,6 +217,7 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
OverTolerance.setUnit(Base::Unit::Length);
|
||||
UnderTolerance.setUnit(Base::Unit::Length);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (prop == &TheoreticalExact) {
|
||||
// if TheoreticalExact disable tolerances and set them to zero
|
||||
@@ -237,7 +240,7 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
FormatSpecUnderTolerance.setReadOnly(false);
|
||||
}
|
||||
}
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
else if (prop == &EqualTolerance) {
|
||||
// if EqualTolerance set negated overtolerance for untertolerance
|
||||
@@ -261,7 +264,7 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
FormatSpecUnderTolerance.setReadOnly(false);
|
||||
}
|
||||
}
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
else if (prop == &OverTolerance) {
|
||||
// if EqualTolerance set negated overtolerance for untertolerance
|
||||
@@ -269,27 +272,19 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
UnderTolerance.setValue(-1.0 * OverTolerance.getValue());
|
||||
UnderTolerance.setUnit(OverTolerance.getUnit());
|
||||
}
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
else if (prop == &FormatSpecOverTolerance) {
|
||||
if (!ArbitraryTolerances.getValue()) {
|
||||
FormatSpecUnderTolerance.setValue(FormatSpecOverTolerance.getValue());
|
||||
}
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
else if (prop == &FormatSpecUnderTolerance) {
|
||||
if (!ArbitraryTolerances.getValue()) {
|
||||
FormatSpecOverTolerance.setValue(FormatSpecUnderTolerance.getValue());
|
||||
}
|
||||
requestPaint();
|
||||
}
|
||||
else if ( (prop == &FormatSpec) ||
|
||||
(prop == &Arbitrary) ||
|
||||
(prop == &ArbitraryTolerances) ||
|
||||
(prop == &MeasureType) ||
|
||||
(prop == &UnderTolerance) ||
|
||||
(prop == &Inverted) ) {
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,21 +348,9 @@ void DrawViewDimension::handleChangedPropertyType(Base::XMLReader &reader, const
|
||||
short DrawViewDimension::mustExecute() const
|
||||
{
|
||||
if (!isRestoring()) {
|
||||
if (
|
||||
References2D.isTouched() ||
|
||||
Type.isTouched() ||
|
||||
FormatSpec.isTouched() ||
|
||||
Arbitrary.isTouched() ||
|
||||
FormatSpecOverTolerance.isTouched() ||
|
||||
FormatSpecUnderTolerance.isTouched() ||
|
||||
ArbitraryTolerances.isTouched() ||
|
||||
MeasureType.isTouched() ||
|
||||
TheoreticalExact.isTouched() ||
|
||||
EqualTolerance.isTouched() ||
|
||||
OverTolerance.isTouched() ||
|
||||
UnderTolerance.isTouched() ||
|
||||
Inverted.isTouched()
|
||||
) {
|
||||
if (References2D.isTouched() ||
|
||||
References3D.isTouched() ||
|
||||
Type.isTouched() ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -377,6 +360,7 @@ short DrawViewDimension::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *DrawViewDimension::execute()
|
||||
{
|
||||
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
|
||||
if (!keepUpdated()) {
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
@@ -396,12 +380,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute()
|
||||
|
||||
//can't do anything until Source has geometry
|
||||
if (!getViewPart()->hasGeometry()) { //happens when loading saved document
|
||||
//if (isRestoring() ||
|
||||
// getDocument()->testStatus(App::Document::Status::Restoring)) {
|
||||
return App::DocumentObject::StdReturn;
|
||||
//} else {
|
||||
// return App::DocumentObject::StdReturn;
|
||||
//}
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
//now we can check if Reference2ds have valid targets.
|
||||
|
||||
@@ -438,8 +438,7 @@ void DrawViewPart::postHlrTasks(void)
|
||||
for (auto& b : bals) {
|
||||
b->recomputeFeature();
|
||||
}
|
||||
// Dimensions need to be recomputed now, unless their recomputation must be postponed
|
||||
// until face creation, in which case they are recomputed after that
|
||||
// Dimensions need to be recomputed now if face finding is not going to take place.
|
||||
if (!handleFaces() || CoarseView.getValue()) {
|
||||
std::vector<TechDraw::DrawViewDimension*> dims = getDimensions();
|
||||
for (auto& d : dims) {
|
||||
@@ -467,9 +466,8 @@ void DrawViewPart::postFaceExtractionTasks(void)
|
||||
// Some centerlines depend on faces so we could not add CL geometry before now
|
||||
addCenterLinesToGeom();
|
||||
|
||||
// Dimensions need to be recomputed here because their
|
||||
// references will be invalid until all the geometry exists,
|
||||
// specifically cosmetic centerlines
|
||||
// Dimensions need to be recomputed because their references will be invalid
|
||||
// until all the geometry (including centerlines dependent on faces) exists.
|
||||
std::vector<TechDraw::DrawViewDimension*> dims = getDimensions();
|
||||
for (auto& d : dims) {
|
||||
d->recomputeFeature();
|
||||
|
||||
@@ -146,7 +146,7 @@ DrawViewSection::DrawViewSection() :
|
||||
static const char *ggroup = "Cut Operation";
|
||||
|
||||
//general section properties
|
||||
ADD_PROPERTY_TYPE(SectionSymbol ,(""), sgroup, App::Prop_None, "The identifier for this section");
|
||||
ADD_PROPERTY_TYPE(SectionSymbol ,(""), sgroup, App::Prop_Output, "The identifier for this section");
|
||||
ADD_PROPERTY_TYPE(BaseView ,(nullptr), sgroup, App::Prop_None, "2D View source for this Section");
|
||||
BaseView.setScope(App::LinkScope::Global);
|
||||
ADD_PROPERTY_TYPE(SectionNormal ,(0, 0,1.0) ,sgroup, App::Prop_None,
|
||||
@@ -234,23 +234,31 @@ void DrawViewSection::onChanged(const App::Property* prop)
|
||||
|
||||
if (prop == &SectionNormal) {
|
||||
Direction.setValue(SectionNormal.getValue());
|
||||
return;
|
||||
} else if (prop == &SectionSymbol) {
|
||||
std::string lblText = "Section " +
|
||||
std::string(SectionSymbol.getValue()) +
|
||||
" - " +
|
||||
std::string(SectionSymbol.getValue());
|
||||
Label.setValue(lblText);
|
||||
if (getBaseDVP()) {
|
||||
getBaseDVP()->requestPaint();
|
||||
}
|
||||
return;
|
||||
} else if (prop == &CutSurfaceDisplay) {
|
||||
if (CutSurfaceDisplay.isValue("PatHatch")) {
|
||||
makeLineSets();
|
||||
}
|
||||
requestPaint();
|
||||
return;
|
||||
} else if (prop == &FileHatchPattern) {
|
||||
replaceSvgIncluded(FileHatchPattern.getValue());
|
||||
requestPaint();
|
||||
return;
|
||||
} else if (prop == &FileGeomPattern) {
|
||||
replacePatIncluded(FileGeomPattern.getValue());
|
||||
makeLineSets();
|
||||
requestPaint();
|
||||
return;
|
||||
} else if (prop == &NameGeomPattern ) {
|
||||
makeLineSets();
|
||||
requestPaint();
|
||||
return;
|
||||
}
|
||||
|
||||
DrawView::onChanged(prop);
|
||||
@@ -286,13 +294,29 @@ App::DocumentObjectExecReturn *DrawViewSection::execute()
|
||||
return new App::DocumentObjectExecReturn("BaseView object not found");
|
||||
}
|
||||
|
||||
if (waitingForCut() || waitingForHlr()) {
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
TopoDS_Shape baseShape = getShapeToCut();
|
||||
|
||||
if (baseShape.IsNull()) {
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
m_saveShape = baseShape; //save shape for 2nd pass
|
||||
//is SectionOrigin valid?
|
||||
Bnd_Box centerBox;
|
||||
BRepBndLib::AddOptimal(baseShape, centerBox);
|
||||
centerBox.SetGap(0.0);
|
||||
Base::Vector3d orgPnt = SectionOrigin.getValue();
|
||||
|
||||
if(!isReallyInBox(gp_Pnt(orgPnt.x, orgPnt.y, orgPnt.z), centerBox)) {
|
||||
Base::Console().Warning("DVS: SectionOrigin doesn't intersect part in %s\n", getNameInDocument());
|
||||
}
|
||||
|
||||
//save important info for later use
|
||||
m_shapeSize = sqrt(centerBox.SquareExtent());
|
||||
m_saveShape = baseShape;
|
||||
|
||||
bool haveX = checkXDirection();
|
||||
if (!haveX) {
|
||||
@@ -334,6 +358,8 @@ void DrawViewSection::sectionExec(TopoDS_Shape& baseShape)
|
||||
return;
|
||||
}
|
||||
|
||||
m_cuttingTool = makeCuttingTool(m_shapeSize);
|
||||
|
||||
try {
|
||||
//note that &m_cutWatcher in the third parameter is not strictly required, but using the
|
||||
//4 parameter signature instead of the 3 parameter signature prevents clazy warning:
|
||||
@@ -357,18 +383,6 @@ void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape)
|
||||
|
||||
showProgressMessage(getNameInDocument(), "is making section cut");
|
||||
|
||||
// cut base shape with tool
|
||||
//is SectionOrigin valid?
|
||||
Bnd_Box centerBox;
|
||||
BRepBndLib::AddOptimal(baseShape, centerBox);
|
||||
centerBox.SetGap(0.0);
|
||||
Base::Vector3d orgPnt = SectionOrigin.getValue();
|
||||
|
||||
if(!isReallyInBox(gp_Pnt(orgPnt.x, orgPnt.y, orgPnt.z), centerBox)) {
|
||||
Base::Console().Warning("DVS: SectionOrigin doesn't intersect part in %s\n", getNameInDocument());
|
||||
}
|
||||
m_shapeSize = sqrt(centerBox.SquareExtent());
|
||||
|
||||
// We need to copy the shape to not modify the BRepstructure
|
||||
BRepBuilderAPI_Copy BuilderCopy(baseShape);
|
||||
TopoDS_Shape myShape = BuilderCopy.Shape();
|
||||
@@ -378,8 +392,6 @@ void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape)
|
||||
BRepTools::Write(myShape, "DVSCopy.brep"); //debug
|
||||
}
|
||||
|
||||
m_cuttingTool = makeCuttingTool(m_shapeSize);
|
||||
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_cuttingTool, "DVSTool.brep"); //debug
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public:
|
||||
bool showSectionEdges(void);
|
||||
|
||||
public Q_SLOTS:
|
||||
void onSectionCutFinished(void);
|
||||
virtual void onSectionCutFinished(void);
|
||||
|
||||
protected:
|
||||
TopoDS_Compound m_sectionTopoDSFaces; //needed for hatching
|
||||
|
||||
@@ -514,6 +514,8 @@ bool TaskComplexSection::apply(bool forceUpdate)
|
||||
}
|
||||
|
||||
Gui::WaitCursor wc;
|
||||
m_modelIsDirty = true;
|
||||
|
||||
if (!m_section) {
|
||||
createComplexSection();
|
||||
}
|
||||
@@ -622,6 +624,12 @@ void TaskComplexSection::createComplexSection()
|
||||
m_section->SectionDirection.setValue("Aligned");
|
||||
m_section->Source.setValues(m_shapes);
|
||||
m_section->XSource.setValues(m_xShapes);
|
||||
|
||||
//auto orientation of view relative to base view
|
||||
double viewDirectionAngle = m_compass->positiveValue();
|
||||
double rotation = requiredRotation(viewDirectionAngle);
|
||||
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.Rotation = %.6f",
|
||||
m_sectionName.c_str(), rotation);
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
@@ -667,6 +675,12 @@ void TaskComplexSection::updateComplexSection()
|
||||
m_section->Source.setValues(m_shapes);
|
||||
m_section->XSource.setValues(m_xShapes);
|
||||
}
|
||||
|
||||
//auto orientation of view relative to base view
|
||||
double viewDirectionAngle = m_compass->positiveValue();
|
||||
double rotation = requiredRotation(viewDirectionAngle);
|
||||
Command::doCommand(Command::Doc, "App.ActiveDocument.%s.Rotation = %.6f",
|
||||
m_sectionName.c_str(), rotation);
|
||||
}
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
@@ -703,6 +717,20 @@ bool TaskComplexSection::isSectionValid()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//get required rotation from input angle in [0, 360]
|
||||
//NOTE: shared code with simple section - reuse opportunity
|
||||
double TaskComplexSection::requiredRotation(double inputAngle)
|
||||
{
|
||||
double rotation = inputAngle - 90.0;
|
||||
if (rotation == 180.0) {
|
||||
//if the view direction is 90/270, then the section is drawn properly and no
|
||||
//rotation is needed. 90.0 becomes 0.0, but 270.0 needs special handling.
|
||||
rotation = 0.0;
|
||||
}
|
||||
return rotation;
|
||||
}
|
||||
|
||||
//******************************************************************************
|
||||
bool TaskComplexSection::accept()
|
||||
{
|
||||
|
||||
@@ -106,6 +106,8 @@ protected Q_SLOTS:
|
||||
void slotViewDirectionChanged(Base::Vector3d newDirection);
|
||||
|
||||
private:
|
||||
double requiredRotation(double inputAngle);
|
||||
|
||||
void createComplexSection();
|
||||
void updateComplexSection();
|
||||
|
||||
|
||||
@@ -138,9 +138,9 @@ bool ViewProviderDimension::setEdit(int ModNum)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderDimension::updateData(const App::Property* p)
|
||||
void ViewProviderDimension::updateData(const App::Property* prop)
|
||||
{
|
||||
if (p == &(getViewObject()->Type)) {
|
||||
if (prop == &(getViewObject()->Type)) {
|
||||
if (getViewObject()->Type.isValue("DistanceX")) {
|
||||
sPixmap = "TechDraw_HorizontalDimension";
|
||||
} else if (getViewObject()->Type.isValue("DistanceY")) {
|
||||
@@ -154,20 +154,33 @@ void ViewProviderDimension::updateData(const App::Property* p)
|
||||
} else if (getViewObject()->Type.isValue("Angle3Pt")) {
|
||||
sPixmap = "TechDraw_3PtAngleDimension";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Dimension handles X, Y updates differently that other QGIView
|
||||
//call QGIViewDimension::updateView
|
||||
if (p == &(getViewObject()->X) ||
|
||||
p == &(getViewObject()->Y) ){
|
||||
if (prop == &(getViewObject()->X) ||
|
||||
prop == &(getViewObject()->Y) ||
|
||||
prop == &(getViewObject()->FormatSpec) ||
|
||||
prop == &(getViewObject()->Arbitrary) ||
|
||||
prop == &(getViewObject()->FormatSpecOverTolerance) ||
|
||||
prop == &(getViewObject()->FormatSpecUnderTolerance) ||
|
||||
prop == &(getViewObject()->ArbitraryTolerances) ||
|
||||
prop == &(getViewObject()->MeasureType) ||
|
||||
prop == &(getViewObject()->TheoreticalExact) ||
|
||||
prop == &(getViewObject()->EqualTolerance) ||
|
||||
prop == &(getViewObject()->OverTolerance) ||
|
||||
prop == &(getViewObject()->UnderTolerance) ||
|
||||
prop == &(getViewObject()->Inverted) ){
|
||||
QGIView* qgiv = getQView();
|
||||
if (qgiv) {
|
||||
qgiv->updateView(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Skip QGIView X, Y processing - do not call ViewProviderDrawingView
|
||||
Gui::ViewProviderDocumentObject::updateData(p);
|
||||
Gui::ViewProviderDocumentObject::updateData(prop);
|
||||
}
|
||||
|
||||
void ViewProviderDimension::onChanged(const App::Property* p)
|
||||
|
||||
Reference in New Issue
Block a user