[TD]move section cut and detail common to thread
This commit is contained in:
committed by
WandererFan
parent
ae3a955877
commit
2c19c29d3c
@@ -66,8 +66,9 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
# include <QFile>
|
||||
# include <QFileInfo>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include "QtConcurrent/qtconcurrentrun.h"
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
@@ -102,7 +103,8 @@ using namespace std;
|
||||
|
||||
PROPERTY_SOURCE(TechDraw::DrawViewDetail, TechDraw::DrawViewPart)
|
||||
|
||||
DrawViewDetail::DrawViewDetail()
|
||||
DrawViewDetail::DrawViewDetail() :
|
||||
m_waitingForDetail(false)
|
||||
{
|
||||
static const char *dgroup = "Detail";
|
||||
|
||||
@@ -192,30 +194,25 @@ void DrawViewDetail::onChanged(const App::Property* prop)
|
||||
|
||||
App::DocumentObjectExecReturn *DrawViewDetail::execute()
|
||||
{
|
||||
// Base::Console().Message("DVD::execute() - %s\n", Label.getValue());
|
||||
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
|
||||
if (!keepUpdated()) {
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
App::DocumentObject* baseObj = BaseView.getValue();
|
||||
if (!baseObj) {
|
||||
bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring);
|
||||
if (isRestoring) {
|
||||
Base::Console().Warning("DVD::execute - No BaseView (but document is restoring) - %s\n",
|
||||
getNameInDocument());
|
||||
} else {
|
||||
Base::Console().Error("Error: DVD::execute - No BaseView(s) linked. - %s\n",
|
||||
Base::Console().Log("DVD::execute - No BaseView(s) linked. - %s\n",
|
||||
getNameInDocument());
|
||||
}
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
DrawViewPart* dvp = nullptr;
|
||||
if (!baseObj->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
|
||||
return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");
|
||||
Base::Console().Log("DVD::execute - %s - BaseView object is not a DrawViewPart object\n",
|
||||
getNameInDocument());
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
dvp = static_cast<DrawViewPart*>(baseObj);
|
||||
DrawViewPart* dvp = static_cast<DrawViewPart*>(baseObj);
|
||||
|
||||
DrawProjGroupItem* dpgi = nullptr;
|
||||
if (dvp->isDerivedFrom(TechDraw::DrawProjGroupItem::getClassTypeId())) {
|
||||
@@ -239,14 +236,8 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
|
||||
}
|
||||
|
||||
if (shape.IsNull()) {
|
||||
bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring);
|
||||
if (isRestoring) {
|
||||
Base::Console().Warning("DVD::execute - source shape is invalid - (but document is restoring) - %s\n",
|
||||
getNameInDocument());
|
||||
} else {
|
||||
Base::Console().Error("Error: DVD::execute - Source shape is Null. - %s\n",
|
||||
getNameInDocument());
|
||||
}
|
||||
Base::Console().Log("DVD::execute - %s - Source shape is Null\n",
|
||||
getNameInDocument());
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
@@ -279,14 +270,32 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
|
||||
|
||||
//try to create a detail of the solids & shells in shape
|
||||
//if there are no solids/shells in shape, use the edges in shape
|
||||
void DrawViewDetail::detailExec(TopoDS_Shape shape,
|
||||
void DrawViewDetail::detailExec(TopoDS_Shape& shape,
|
||||
DrawViewPart* dvp,
|
||||
DrawViewSection* dvs)
|
||||
{
|
||||
if (waitingForResult()) {
|
||||
Base::Console().Message("DVD::detailExec - waiting for result\n");
|
||||
// Base::Console().Message("DVD::detailExec - waiting for result\n");
|
||||
return;
|
||||
}
|
||||
QObject::connect(&m_detailWatcher, SIGNAL(finished()), this, SLOT(onMakeDetailFinished()));
|
||||
m_detailFuture = QtConcurrent::run(this, &DrawViewDetail::makeDetailShape, shape, dvp, dvs);
|
||||
m_detailWatcher.setFuture(m_detailFuture);
|
||||
}
|
||||
|
||||
//this runs in a separate thread since it can sometimes take a long time
|
||||
void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
|
||||
DrawViewPart* dvp,
|
||||
DrawViewSection* dvs)
|
||||
{
|
||||
if (waitingForDetail()) {
|
||||
// Base::Console().Message("DVD::makeDetailShape - already in progress. returning\n");
|
||||
return;
|
||||
}
|
||||
waitingForDetail(true);
|
||||
showProgressMessage(getNameInDocument(), "is making detail shape");
|
||||
|
||||
// auto start = chrono::high_resolution_clock::now();
|
||||
|
||||
Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point (in unrotated coords)
|
||||
Base::Vector3d dirDetail = dvp->Direction.getValue();
|
||||
@@ -314,11 +323,9 @@ void DrawViewDetail::detailExec(TopoDS_Shape shape,
|
||||
shapeCenter = Base::Vector3d(0.0, 0.0, 0.0);
|
||||
|
||||
|
||||
gp_Ax2 viewAxis;
|
||||
|
||||
viewAxis = dvp->getProjectionCS(shapeCenter);
|
||||
m_viewAxis = dvp->getProjectionCS(shapeCenter);
|
||||
anchor = Base::Vector3d(anchor.x,anchor.y, 0.0); //anchor coord in projection CS
|
||||
Base::Vector3d anchorOffset3d = DrawUtil::toR3(viewAxis, anchor); //actual anchor coords in R3
|
||||
Base::Vector3d anchorOffset3d = DrawUtil::toR3(m_viewAxis, anchor); //actual anchor coords in R3
|
||||
|
||||
Bnd_Box bbxSource;
|
||||
bbxSource.SetGap(0.0);
|
||||
@@ -434,59 +441,77 @@ void DrawViewDetail::detailExec(TopoDS_Shape shape,
|
||||
//centroid of result
|
||||
inputCenter = TechDraw::findCentroid(pieces,
|
||||
dirDetail);
|
||||
Base::Vector3d centroid(inputCenter.X(),
|
||||
inputCenter.Y(),
|
||||
inputCenter.Z());
|
||||
m_saveCentroid += centroid; //center of massaged shape
|
||||
Base::Vector3d centroid(inputCenter.X(),
|
||||
inputCenter.Y(),
|
||||
inputCenter.Z());
|
||||
m_saveCentroid += centroid; //center of massaged shape
|
||||
|
||||
TopoDS_Shape scaledShape;
|
||||
if ((solidCount > 0) ||
|
||||
(shellCount > 0)) {
|
||||
//align shape with detail anchor
|
||||
TopoDS_Shape centeredShape = TechDraw::moveShape(pieces,
|
||||
anchorOffset3d * -1.0);
|
||||
scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
if (debugDetail()) {
|
||||
BRepTools::Write(scaledShape, "DVDScaled.brep"); //debug
|
||||
if ((solidCount > 0) ||
|
||||
(shellCount > 0)) {
|
||||
//align shape with detail anchor
|
||||
TopoDS_Shape centeredShape = TechDraw::moveShape(pieces,
|
||||
anchorOffset3d * -1.0);
|
||||
m_scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
if (debugDetail()) {
|
||||
BRepTools::Write(m_scaledShape, "DVDScaled.brep"); //debug
|
||||
}
|
||||
} else {
|
||||
//no solids, no shells, do what you can with edges
|
||||
TopoDS_Shape projectedEdges = projectEdgesOntoFace(myShape, aProjFace, gdir);
|
||||
TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges,
|
||||
anchorOffset3d * -1.0);
|
||||
if (debugDetail()) {
|
||||
BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep"); //debug
|
||||
BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug
|
||||
}
|
||||
m_scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
}
|
||||
} else {
|
||||
//no solids, no shells, do what you can with edges
|
||||
TopoDS_Shape projectedEdges = projectEdgesOntoFace(myShape, aProjFace, gdir);
|
||||
TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges,
|
||||
anchorOffset3d * -1.0);
|
||||
if (debugDetail()) {
|
||||
BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep"); //debug
|
||||
BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug
|
||||
|
||||
Base::Vector3d stdOrg(0.0,0.0,0.0);
|
||||
m_viewAxis = dvp->getProjectionCS(stdOrg);
|
||||
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
|
||||
m_scaledShape = TechDraw::rotateShape(m_scaledShape,
|
||||
m_viewAxis,
|
||||
Rotation.getValue());
|
||||
}
|
||||
scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
}
|
||||
} //end try block
|
||||
|
||||
Base::Vector3d stdOrg(0.0,0.0,0.0);
|
||||
gp_Ax2 viewAxis = dvp->getProjectionCS(stdOrg);
|
||||
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
|
||||
scaledShape = TechDraw::rotateShape(scaledShape,
|
||||
viewAxis,
|
||||
Rotation.getValue());
|
||||
}
|
||||
|
||||
geometryObject = buildGeometryObject(scaledShape,viewAxis);
|
||||
}
|
||||
catch (Standard_Failure& e1) {
|
||||
Base::Console().Message("LOG - DVD::execute - failed to create detail %s - %s **\n",getNameInDocument(),e1.GetMessageString());
|
||||
Base::Console().Message("DVD::makeDetailShape - failed to create detail %s - %s **\n",getNameInDocument(),e1.GetMessageString());
|
||||
return;
|
||||
}
|
||||
|
||||
// auto end = chrono::high_resolution_clock::now();
|
||||
// auto diff = end - start;
|
||||
// double diffOut = chrono::duration <double, milli>(diff).count();
|
||||
// Base::Console().Message("DVD::makeDetailShape - %s spent: %.3f millisecs making detail shape\n", getNameInDocument(), diffOut);
|
||||
showProgressMessage(getNameInDocument(), "has finished making detail shape");
|
||||
}
|
||||
|
||||
void DrawViewDetail::postHlrTasks(void)
|
||||
{
|
||||
// Base::Console().Message("DVD::postHlrTasks()\n");
|
||||
geometryObject->pruneVertexGeom(Base::Vector3d(0.0,0.0,0.0),
|
||||
Radius.getValue() * getScale()); //remove vertices beyond clipradius
|
||||
DrawViewPart::postHlrTasks();
|
||||
}
|
||||
|
||||
TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape edgeShape, TopoDS_Face projFace, gp_Dir projDir)
|
||||
//continue processing after makeDetailShape thread is finished
|
||||
void DrawViewDetail::onMakeDetailFinished(void)
|
||||
{
|
||||
waitingForDetail(false);
|
||||
QObject::disconnect(&m_detailWatcher, SIGNAL(finished()), this, SLOT(onMakeDetailFinished()));
|
||||
|
||||
//ancestor's buildGeometryObject will run HLR and face finding in a separate thread
|
||||
geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis);
|
||||
|
||||
}
|
||||
TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape &edgeShape,
|
||||
TopoDS_Face &projFace,
|
||||
gp_Dir& projDir)
|
||||
{
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound edges;
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
#ifndef _DrawViewDetail_h_
|
||||
#define _DrawViewDetail_h_
|
||||
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <App/FeaturePython.h>
|
||||
@@ -47,6 +50,7 @@ namespace TechDraw
|
||||
class TechDrawExport DrawViewDetail : public DrawViewPart
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Part::DrawViewDetail);
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
@@ -67,22 +71,37 @@ public:
|
||||
void unsetupObject() override;
|
||||
|
||||
|
||||
void detailExec(TopoDS_Shape s,
|
||||
void detailExec(TopoDS_Shape& s,
|
||||
DrawViewPart* baseView,
|
||||
DrawViewSection* sectionAlias);
|
||||
double getFudgeRadius();
|
||||
TopoDS_Shape projectEdgesOntoFace(TopoDS_Shape edgeShape, TopoDS_Face projFace, gp_Dir projDir);
|
||||
void makeDetailShape(TopoDS_Shape& shape,
|
||||
DrawViewPart* dvp,
|
||||
DrawViewSection* dvs);
|
||||
void postHlrTasks(void) override;
|
||||
void waitingForDetail(bool s) { m_waitingForDetail = s; }
|
||||
bool waitingForDetail(void) { return m_waitingForDetail; }
|
||||
|
||||
double getFudgeRadius(void);
|
||||
TopoDS_Shape projectEdgesOntoFace(TopoDS_Shape& edgeShape,
|
||||
TopoDS_Face& projFace,
|
||||
gp_Dir& projDir);
|
||||
|
||||
std::vector<DrawViewDetail*> getDetailRefs() const override;
|
||||
|
||||
void postHlrTasks(void) override;
|
||||
public Q_SLOTS:
|
||||
void onMakeDetailFinished(void);
|
||||
|
||||
protected:
|
||||
Base::Vector3d toR3(const gp_Ax2 fromSystem, const Base::Vector3d fromPoint);
|
||||
void getParameters();
|
||||
void getParameters(void);
|
||||
double m_fudge;
|
||||
bool debugDetail() const;
|
||||
|
||||
TopoDS_Shape m_scaledShape;
|
||||
gp_Ax2 m_viewAxis;
|
||||
|
||||
QFutureWatcher<void> m_detailWatcher;
|
||||
QFuture<void> m_detailFuture;
|
||||
bool m_waitingForDetail;
|
||||
};
|
||||
|
||||
typedef App::FeaturePythonT<DrawViewDetail> DrawViewDetailPython;
|
||||
|
||||
@@ -287,36 +287,26 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
|
||||
if (!keepUpdated()) {
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
if (waitingForResult()) {
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
App::Document* doc = getDocument();
|
||||
bool isRestoring = doc->testStatus(App::Document::Status::Restoring);
|
||||
const std::vector<App::DocumentObject*>& links = getAllSources();
|
||||
if (links.empty()) {
|
||||
if (isRestoring) {
|
||||
Base::Console().Warning("DVP::execute - No Sources (but document is restoring) - %s\n",
|
||||
getNameInDocument());
|
||||
} else {
|
||||
Base::Console().Error("Error: DVP::execute - No Source(s) linked. - %s\n",
|
||||
getNameInDocument());
|
||||
}
|
||||
return App::DocumentObject::StdReturn;
|
||||
Base::Console().Log("DVP::execute - %s - No Source(s) linked.\n",
|
||||
getNameInDocument());
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
TopoDS_Shape shape = getSourceShape();
|
||||
if (shape.IsNull()) {
|
||||
if (isRestoring) {
|
||||
Base::Console().Warning("DVP::execute - source shape is invalid - (but document is restoring) - %s\n",
|
||||
getNameInDocument());
|
||||
} else {
|
||||
Base::Console().Error("Error: DVP::execute - Source shape is Null. - %s\n",
|
||||
getNameInDocument());
|
||||
}
|
||||
return App::DocumentObject::StdReturn;
|
||||
Base::Console().Log("DVP::execute - %s - Source shape is Null.\n",
|
||||
getNameInDocument());
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
|
||||
bool haveX = checkXDirection();
|
||||
if (!haveX) {
|
||||
if (!checkXDirection()) {
|
||||
//block touch/onChanged stuff
|
||||
Base::Vector3d newX = getXDirection();
|
||||
XDirection.setValue(newX);
|
||||
@@ -381,11 +371,9 @@ void DrawViewPart::onChanged(const App::Property* prop)
|
||||
}
|
||||
|
||||
DrawView::onChanged(prop);
|
||||
|
||||
//TODO: when scale changes, any Dimensions for this View sb recalculated. DVD should pick this up subject to topological naming issues.
|
||||
}
|
||||
|
||||
void DrawViewPart::partExec(TopoDS_Shape shape)
|
||||
void DrawViewPart::partExec(TopoDS_Shape& shape)
|
||||
{
|
||||
// Base::Console().Message("DVP::partExec()\n");
|
||||
if (waitingForResult()) {
|
||||
@@ -402,19 +390,15 @@ void DrawViewPart::partExec(TopoDS_Shape shape)
|
||||
geometryObject = makeGeometryForShape(shape);
|
||||
}
|
||||
|
||||
GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape shape)
|
||||
GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape)
|
||||
{
|
||||
// Base::Console().Message("DVP::makeGeometryForShape()\n");
|
||||
// BRepTools::Write(shape, "DVPShape.brep"); //debug
|
||||
gp_Pnt inputCenter;
|
||||
Base::Vector3d stdOrg(0.0,0.0,0.0);
|
||||
|
||||
gp_Ax2 viewAxis = getProjectionCS(stdOrg);
|
||||
|
||||
// BRepTools::Write(shape, "DVPShape.brep"); //debug
|
||||
|
||||
inputCenter = TechDraw::findCentroid(shape,
|
||||
viewAxis);
|
||||
|
||||
Base::Vector3d centroid(inputCenter.X(),
|
||||
inputCenter.Y(),
|
||||
inputCenter.Z());
|
||||
@@ -438,7 +422,7 @@ GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape shape)
|
||||
}
|
||||
|
||||
//note: slightly different than routine with same name in DrawProjectSplit
|
||||
TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis)
|
||||
TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis)
|
||||
{
|
||||
// Base::Console().Message("DVP::buildGeometryObject()\n");
|
||||
TechDraw::GeometryObject* go = new TechDraw::GeometryObject(getNameInDocument(), this);
|
||||
@@ -454,12 +438,12 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape shape,
|
||||
//the post hlr processing manually
|
||||
} else {
|
||||
// Base::Console().Message("DVP::buildGeometryObject - starting projectShape\n");
|
||||
waitingForHlr(true);
|
||||
//project shape runs in a separate thread since if can take a long time
|
||||
QObject::connect(&m_hlrWatcher, SIGNAL(finished()), this, SLOT(onHlrFinished()));
|
||||
m_hlrFuture = QtConcurrent::run(go, &GeometryObject::projectShape, shape, viewAxis);
|
||||
m_hlrWatcher.setFuture(m_hlrFuture);
|
||||
waitingForHlr(true);
|
||||
}
|
||||
|
||||
return go;
|
||||
}
|
||||
|
||||
@@ -473,11 +457,11 @@ void DrawViewPart::onHlrFinished(void)
|
||||
|
||||
waitingForHlr(false);
|
||||
QObject::disconnect(&m_hlrWatcher, SIGNAL(finished()), this, SLOT(onHlrFinished()));
|
||||
|
||||
showProgressMessage(getNameInDocument(), "has finished finding hidden lines");
|
||||
|
||||
postHlrTasks();
|
||||
|
||||
//start face finding in a separate thread
|
||||
if (handleFaces() && !CoarseView.getValue()) {
|
||||
try {
|
||||
// Base::Console().Message("DVP::onHlrFinished - starting extractFaces\n");
|
||||
@@ -485,26 +469,25 @@ void DrawViewPart::onHlrFinished(void)
|
||||
m_faceFuture = QtConcurrent::run(this, &DrawViewPart::extractFaces);
|
||||
m_faceWatcher.setFuture(m_faceFuture);
|
||||
}
|
||||
catch (Standard_Failure& e4) {
|
||||
catch (Standard_Failure& e) {
|
||||
waitingForFaces(false);
|
||||
Base::Console().Message("DVP::partExec - extractFaces failed for %s - %s **\n",getNameInDocument(),e4.GetMessageString());
|
||||
Base::Console().Error("DVP::partExec - %s - extractFaces failed - %s **\n",getNameInDocument(), e.GetMessageString());
|
||||
throw Base::RuntimeError("DVP::onHlrFinished - error extracting faces");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//run any tasks that need to been done after geometry is available
|
||||
void DrawViewPart::postHlrTasks(void)
|
||||
{
|
||||
//add geometry that doesn't come from HLR
|
||||
addCosmeticVertexesToGeom();
|
||||
addCosmeticEdgesToGeom();
|
||||
addCenterLinesToGeom();
|
||||
|
||||
addReferencesToGeom();
|
||||
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
void DrawViewPart::postHlrTasks(void)
|
||||
{
|
||||
//DVDetail and DVSection have special needs.
|
||||
//dimensions and balloons need to be recomputed here to get their references sorted
|
||||
|
||||
//dimensions and balloons need to be recomputed here because their
|
||||
//references will be invalid until the geometry exists
|
||||
std::vector<TechDraw::DrawViewDimension*> dims = getDimensions();
|
||||
for (auto& d : dims) {
|
||||
d->recomputeFeature();
|
||||
@@ -513,6 +496,8 @@ void DrawViewPart::postHlrTasks(void)
|
||||
for (auto& b : bals) {
|
||||
b->recomputeFeature();
|
||||
}
|
||||
|
||||
requestPaint();
|
||||
}
|
||||
|
||||
//! make faces from the existing edge geometry
|
||||
|
||||
@@ -226,10 +226,10 @@ protected:
|
||||
void onChanged(const App::Property* prop) override;
|
||||
void unsetupObject() override;
|
||||
|
||||
virtual TechDraw::GeometryObject* buildGeometryObject(TopoDS_Shape shape, gp_Ax2 viewAxis); //const??
|
||||
virtual TechDraw::GeometryObject* makeGeometryForShape(TopoDS_Shape shape); //const??
|
||||
void partExec(TopoDS_Shape shape);
|
||||
virtual void addShapes2d();
|
||||
virtual TechDraw::GeometryObject* buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis);
|
||||
virtual TechDraw::GeometryObject* makeGeometryForShape(TopoDS_Shape& shape); //const??
|
||||
void partExec(TopoDS_Shape& shape);
|
||||
virtual void addShapes2d(void);
|
||||
|
||||
void extractFaces();
|
||||
|
||||
|
||||
@@ -65,8 +65,9 @@
|
||||
|
||||
#include <chrono>
|
||||
|
||||
# include <QFile>
|
||||
# include <QFileInfo>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include "QtConcurrent/qtconcurrentrun.h"
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
@@ -115,7 +116,8 @@ const char* DrawViewSection::CutSurfaceEnums[]= {"Hide",
|
||||
|
||||
PROPERTY_SOURCE(TechDraw::DrawViewSection, TechDraw::DrawViewPart)
|
||||
|
||||
DrawViewSection::DrawViewSection()
|
||||
DrawViewSection::DrawViewSection() :
|
||||
m_waitingForCut(false)
|
||||
{
|
||||
static const char *sgroup = "Section";
|
||||
static const char *fgroup = "Cut Surface Format";
|
||||
@@ -349,21 +351,42 @@ App::DocumentObjectExecReturn *DrawViewSection::execute()
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
|
||||
void DrawViewSection::sectionExec(TopoDS_Shape& baseShape)
|
||||
{
|
||||
// Base::Console().Message("DVS::sectionExec() - %s\n", getNameInDocument());
|
||||
if (waitingForResult()) {
|
||||
// Base::Console().Message("DVS::sectionExec - waiting for result\n");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
QObject::connect(&m_cutWatcher, SIGNAL(finished()), this, SLOT(onSectionCutFinished()));
|
||||
m_cutFuture = QtConcurrent::run(this, &DrawViewSection::makeSectionCut, baseShape);
|
||||
m_cutWatcher.setFuture(m_cutFuture);
|
||||
}
|
||||
catch (...) {
|
||||
Base::Console().Message("DVS::sectionExec - failed to make section cut");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape)
|
||||
{
|
||||
// Base::Console().Message("DVS::makeSectionCut()\n");
|
||||
if (waitingForCut()) {
|
||||
// Base::Console().Message("DVS::makeSectionCut - waiting for cut - returning\n");
|
||||
return;
|
||||
}
|
||||
|
||||
waitingForCut(true);
|
||||
showProgressMessage(getNameInDocument(), "is making section cut");
|
||||
|
||||
// auto start = chrono::high_resolution_clock::now();
|
||||
|
||||
// cut base shape with tool
|
||||
//is SectionOrigin valid?
|
||||
Bnd_Box centerBox;
|
||||
BRepBndLib::AddOptimal(baseShape, centerBox);
|
||||
centerBox.SetGap(0.0);
|
||||
|
||||
// make tool
|
||||
gp_Pln pln = getSectionPlane();
|
||||
gp_Dir gpNormal = pln.Axis().Direction();
|
||||
Base::Vector3d orgPnt = SectionOrigin.getValue();
|
||||
@@ -372,6 +395,7 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
|
||||
Base::Console().Warning("DVS: SectionOrigin doesn't intersect part in %s\n",getNameInDocument());
|
||||
}
|
||||
|
||||
// make cutting tool
|
||||
// Make the extrusion face
|
||||
double dMax = sqrt(centerBox.SquareExtent());
|
||||
BRepBuilderAPI_MakeFace mkFace(pln, -dMax,dMax,-dMax,dMax);
|
||||
@@ -420,20 +444,19 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
|
||||
BRepBndLib::AddOptimal(rawShape, testBox);
|
||||
testBox.SetGap(0.0);
|
||||
if (testBox.IsVoid()) { //prism & input don't intersect. rawShape is garbage, don't bother.
|
||||
Base::Console().Warning("DVS::execute - prism & input don't intersect - %s\n", Label.getValue());
|
||||
Base::Console().Warning("DVS::makeSectionCut - prism & input don't intersect - %s\n", Label.getValue());
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// build display geometry as in DVP, with minor mods
|
||||
gp_Ax2 viewAxis;
|
||||
TopoDS_Shape centeredShape;
|
||||
try {
|
||||
Base::Vector3d origin(0.0, 0.0, 0.0);
|
||||
viewAxis = getProjectionCS(origin);
|
||||
m_viewAxis = getProjectionCS(origin);
|
||||
gp_Pnt inputCenter;
|
||||
inputCenter = TechDraw::findCentroid(rawShape,
|
||||
viewAxis);
|
||||
m_viewAxis);
|
||||
Base::Vector3d centroid(inputCenter.X(),
|
||||
inputCenter.Y(),
|
||||
inputCenter.Z());
|
||||
@@ -443,36 +466,49 @@ void DrawViewSection::sectionExec(TopoDS_Shape baseShape)
|
||||
m_cutShape = centeredShape;
|
||||
m_saveCentroid = centroid;
|
||||
|
||||
TopoDS_Shape scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
m_scaledShape = TechDraw::scaleShape(centeredShape,
|
||||
getScale());
|
||||
|
||||
if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
|
||||
scaledShape = TechDraw::rotateShape(scaledShape,
|
||||
viewAxis,
|
||||
Rotation.getValue());
|
||||
m_scaledShape = TechDraw::rotateShape(m_scaledShape,
|
||||
m_viewAxis,
|
||||
Rotation.getValue());
|
||||
}
|
||||
if (debugSection()) {
|
||||
BRepTools::Write(m_cutShape, "DVSmCutShape.brep"); //debug
|
||||
BRepTools::Write(scaledShape, "DVSScaled.brep"); //debug
|
||||
// DrawUtil::dumpCS("DVS::execute - CS to GO", viewAxis);
|
||||
BRepTools::Write(m_scaledShape, "DVSScaled.brep"); //debug
|
||||
// DrawUtil::dumpCS("DVS::makeSectionCut - CS to GO", viewAxis);
|
||||
}
|
||||
|
||||
m_rawShape = rawShape; //save for postHlrTasks
|
||||
m_viewAxis= viewAxis; //save for postHlrTasks
|
||||
|
||||
geometryObject = buildGeometryObject(scaledShape,viewAxis);
|
||||
}
|
||||
catch (Standard_Failure& e1) {
|
||||
Base::Console().Warning("DVS::execute - failed to build base shape %s - %s **\n",
|
||||
Base::Console().Warning("DVS::makeSectionCut - failed to build base shape %s - %s **\n",
|
||||
getNameInDocument(),e1.GetMessageString());
|
||||
return;
|
||||
}
|
||||
//display geometry for cut shape is in geometryObject as in DVP
|
||||
|
||||
// auto end = chrono::high_resolution_clock::now();
|
||||
// auto diff = end - start;
|
||||
// double diffOut = chrono::duration <double, milli>(diff).count();
|
||||
// Base::Console().Message("DVS::makeSectionCut - %s spent: %.3f millisecs making section cut\n", getNameInDocument(), diffOut);
|
||||
}
|
||||
|
||||
void DrawViewSection::onSectionCutFinished()
|
||||
{
|
||||
waitingForCut(false);
|
||||
QObject::disconnect(&m_cutWatcher, SIGNAL(finished()), this, SLOT(onSectionCutFinished()));
|
||||
|
||||
//display geometry for cut shape is in geometryObject as in DVP
|
||||
geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis);
|
||||
}
|
||||
|
||||
void DrawViewSection::postHlrTasks(void)
|
||||
{
|
||||
// Base::Console().Message("DVS::postHlrTasks() - %s\n", getNameInDocument());
|
||||
// auto start = chrono::high_resolution_clock::now();
|
||||
|
||||
// build section face geometry
|
||||
TopoDS_Compound faceIntersections = findSectionPlaneIntersections(m_rawShape);
|
||||
TopoDS_Shape centeredShapeF = TechDraw::moveShape(faceIntersections,
|
||||
@@ -538,6 +574,11 @@ void DrawViewSection::postHlrTasks(void)
|
||||
tdSectionFaces.push_back(sectionFace);
|
||||
}
|
||||
|
||||
// auto end = chrono::high_resolution_clock::now();
|
||||
// auto diff = end - start;
|
||||
// double diffOut = chrono::duration <double, milli>(diff).count();
|
||||
// Base::Console().Message("DVS::sectionExec - %s spent: %.3f millisecs finding section faces\n", getNameInDocument(), diffOut);
|
||||
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (base != nullptr) {
|
||||
if (base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
|
||||
@@ -546,6 +587,7 @@ void DrawViewSection::postHlrTasks(void)
|
||||
}
|
||||
}
|
||||
requestPaint();
|
||||
DrawViewPart::postHlrTasks();
|
||||
}
|
||||
|
||||
gp_Pln DrawViewSection::getSectionPlane() const
|
||||
@@ -561,14 +603,14 @@ gp_Pln DrawViewSection::getSectionPlane() const
|
||||
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
|
||||
{
|
||||
// Base::Console().Message("DVS::findSectionPlaneIntersections()\n");
|
||||
TopoDS_Compound result;
|
||||
if(shape.IsNull()){
|
||||
Base::Console().Warning("DrawViewSection::getSectionSurface - Sectional View shape is Empty\n");
|
||||
return result;
|
||||
return TopoDS_Compound();
|
||||
}
|
||||
|
||||
gp_Pln plnSection = getSectionPlane();
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound result;
|
||||
builder.MakeCompound(result);
|
||||
|
||||
TopExp_Explorer expFaces(shape, TopAbs_FACE);
|
||||
@@ -775,23 +817,6 @@ gp_Ax2 DrawViewSection::getSectionCS() const
|
||||
return sectionCS;
|
||||
}
|
||||
|
||||
gp_Ax2 DrawViewSection::rotateCSArbitrary(gp_Ax2 oldCS,
|
||||
Base::Vector3d axis,
|
||||
double degAngle) const
|
||||
{
|
||||
gp_Ax2 newCS;
|
||||
|
||||
gp_Pnt oldOrg = oldCS.Location();
|
||||
|
||||
gp_Dir gAxis(axis.x, axis.y, axis.z);
|
||||
gp_Ax1 rotAxis = gp_Ax1(oldOrg, gAxis);
|
||||
|
||||
double radAngle = degAngle * M_PI / 180.0;
|
||||
|
||||
newCS = oldCS.Rotated(rotAxis, radAngle);
|
||||
return newCS;
|
||||
}
|
||||
|
||||
std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
|
||||
{
|
||||
// Base::Console().Message("DVS::getDrawableLines(%d) - lineSets: %d\n", i, m_lineSets.size());
|
||||
@@ -966,6 +991,8 @@ void DrawViewSection::setupPatIncluded()
|
||||
}
|
||||
}
|
||||
|
||||
#include <Mod/TechDraw/App/moc_DrawViewSection.cpp>
|
||||
|
||||
// Python Drawing feature ---------------------------------------------------------
|
||||
|
||||
namespace App {
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#ifndef _DrawViewSection_h_
|
||||
#define _DrawViewSection_h_
|
||||
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/FeaturePython.h>
|
||||
#include <App/PropertyFile.h>
|
||||
@@ -60,6 +63,7 @@ class DashSet;
|
||||
class TechDrawExport DrawViewSection : public DrawViewPart
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Part::DrawViewSection);
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DrawViewSection();
|
||||
@@ -92,16 +96,17 @@ public:
|
||||
void unsetupObject() override;
|
||||
short mustExecute() const override;
|
||||
|
||||
void sectionExec(TopoDS_Shape s);
|
||||
void sectionExec(TopoDS_Shape& s);
|
||||
void makeSectionCut(TopoDS_Shape &baseShape);
|
||||
void postHlrTasks(void) override;
|
||||
void waitingForCut(bool s) { m_waitingForCut = s; }
|
||||
bool waitingForCut(void) { return m_waitingForCut; }
|
||||
|
||||
std::vector<TechDraw::FacePtr> getTDFaceGeometry() {return tdSectionFaces;}
|
||||
|
||||
void setCSFromBase(const std::string sectionName);
|
||||
gp_Ax2 getCSFromBase(const std::string sectionName) const;
|
||||
|
||||
gp_Ax2 rotateCSArbitrary(gp_Ax2 oldCS,
|
||||
Base::Vector3d axis,
|
||||
double degAngle) const;
|
||||
gp_Ax2 getSectionCS() const;
|
||||
Base::Vector3d getXDirection() const override; //don't use XDirection.getValue()
|
||||
|
||||
@@ -123,7 +128,9 @@ public:
|
||||
std::pair<Base::Vector3d, Base::Vector3d> sectionLineEnds();
|
||||
|
||||
bool showSectionEdges(void);
|
||||
void postHlrTasks(void) override;
|
||||
|
||||
public Q_SLOTS:
|
||||
void onSectionCutFinished(void);
|
||||
|
||||
protected:
|
||||
TopoDS_Compound sectionFaces; //tSectionFaces
|
||||
@@ -149,6 +156,11 @@ protected:
|
||||
|
||||
TopoDS_Shape m_rawShape;
|
||||
gp_Ax2 m_viewAxis;
|
||||
TopoDS_Shape m_scaledShape;
|
||||
|
||||
QFutureWatcher<void> m_cutWatcher;
|
||||
QFuture<void> m_cutFuture;
|
||||
bool m_waitingForCut;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user