[TD]code clean ups

- QtConcurrent include and CMake for Win

- include clean up dvp, dvs, dvd

- variable names and nested if clean up

- remove debug code
This commit is contained in:
Wanderer Fan
2022-07-29 14:17:24 -04:00
committed by WandererFan
parent 459dde957c
commit e97b95341a
36 changed files with 772 additions and 840 deletions

View File

@@ -18,11 +18,22 @@ include_directories(
${QT_QTCORE_INCLUDE_DIR}
)
set(TechDrawLIBS
Measure
Part
Spreadsheet
Import
)
if(BUILD_QT5)
include_directories(
${Qt5XmlPatterns_INCLUDE_DIRS}
${Qt5Concurrent_INCLUDE_DIRS}
)
set(QtXmlPatternsLib ${Qt5XmlPatterns_LIBRARIES})
list(APPEND TechDrawLIBS
${Qt5Concurrent_LIBRARIES}
)
else(BUILD_QT5)
include_directories(
${QT_QTXMLPATTERNS_INCLUDE_DIR}
@@ -32,13 +43,6 @@ endif(BUILD_QT5)
link_directories(${OCC_LIBRARY_DIR})
set(TechDrawLIBS
Measure
Part
Spreadsheet
Import
)
generate_from_xml(DrawPagePy)
generate_from_xml(DrawViewPy)
generate_from_xml(DrawViewPartPy)

View File

@@ -176,15 +176,29 @@ void DrawGeomHatch::makeLineSets()
// Base::Console().Message("DGH::makeLineSets()\n");
if ((!PatIncluded.isEmpty()) &&
(!NamePattern.isEmpty())) {
std::vector<PATLineSpec> specs = getDecodedSpecsFromFile();
m_lineSets.clear();
m_lineSets = makeLineSets(PatIncluded.getValue(),
NamePattern.getValue());
}
}
/*static*/
std::vector<LineSet> DrawGeomHatch::makeLineSets(std::string fileSpec, std::string myPattern)
{
std::vector<LineSet> lineSets;
if ((!fileSpec.empty()) &&
(!myPattern.empty())) {
std::vector<PATLineSpec> specs =
DrawGeomHatch::getDecodedSpecsFromFile(fileSpec,
myPattern);
for (auto& hl: specs) {
//hl.dump("hl from file");
//hl.dump("hl from section");
LineSet ls;
ls.setPATLineSpec(hl);
m_lineSets.push_back(ls);
lineSets.push_back(ls);
}
}
return lineSets;
}
DrawViewPart* DrawGeomHatch::getSourceView() const

View File

@@ -93,7 +93,7 @@ public:
static std::string prefGeomHatchFile(void);
static std::string prefGeomHatchName();
static App::Color prefGeomHatchColor();
static std::vector<LineSet> makeLineSets(std::string fileSpec, std::string myPattern);
protected:
virtual void onDocumentRestored() override;

View File

@@ -142,7 +142,8 @@ App::DocumentObjectExecReturn *DrawLeaderLine::execute()
if (!keepUpdated()) {
return App::DocumentObject::StdReturn;
}
adjustLastSegment();
adjustLastSegment();
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -356,8 +356,11 @@ void DrawPage::updateAllViews()
if (part) {
continue;
}
if (v) {
v->recomputeFeature();
TechDraw::DrawView* view = dynamic_cast<TechDraw::DrawView*>(v);
if (view) {
view->overrideKeepUpdated(true);
view->recomputeFeature();
}
}
}

View File

@@ -62,8 +62,7 @@ const char* DrawProjGroup::ProjectionTypeEnums[] = {"First Angle",
PROPERTY_SOURCE(TechDraw::DrawProjGroup, TechDraw::DrawViewCollection)
DrawProjGroup::DrawProjGroup() :
m_lockScale(false)
DrawProjGroup::DrawProjGroup()
{
static const char *group = "Base";
static const char *agroup = "Distribute";
@@ -115,50 +114,62 @@ void DrawProjGroup::onChanged(const App::Property* prop)
{
//TODO: For some reason, when the projection type is changed, the isometric views show change appropriately, but the orthographic ones don't... Or vice-versa. WF: why would you change from 1st to 3rd in mid drawing?
//if group hasn't been added to page yet, can't scale or distribute projItems
if (isRestoring() || !getPage()) {
return TechDraw::DrawViewCollection::onChanged(prop);
}
TechDraw::DrawPage *page = getPage();
if (!isRestoring() && page) {
if (prop == &Scale) {
if (!m_lockScale) {
if (prop == &Scale) {
updateChildrenScale();
recomputeChildren();
return;
}
if (prop == &ProjectionType) {
updateChildrenEnforce();
return;
}
if ( (prop == &Source) ||
(prop == &XSource) ) {
updateChildrenSource();
return;
}
if ((prop == &spacingX) || (prop == &spacingY)) {
updateChildrenEnforce();
return;
}
if (prop == &LockPosition) {
updateChildrenLock();
return;
}
if (prop == &ScaleType) {
if (ScaleType.isValue("Automatic")) {
//Nothing in particular
} else if (ScaleType.isValue("Page")) {
double newScale = page->Scale.getValue();
if(std::abs(getScale() - newScale) > FLT_EPSILON) {
Scale.setValue(newScale);
updateChildrenScale();
updateChildrenEnforce();
}
} else {
//ScaleType = Custom
}
//DrawView will sort out Scale hidden/readonly/etc
TechDraw::DrawViewCollection::onChanged(prop);
}
if (prop == &ProjectionType) {
updateChildrenEnforce();
}
if ( (prop == &Source) ||
(prop == &XSource) ) {
updateChildrenSource();
}
if ((prop == &spacingX) || (prop == &spacingY)) {
updateChildrenEnforce();
}
if (prop == &LockPosition) {
updateChildrenLock();
}
if (prop == &ScaleType) {
if (ScaleType.isValue("Automatic")) {
//Nothing in particular
} else if (ScaleType.isValue("Page")) {
double newScale = page->Scale.getValue();
if(std::abs(getScale() - newScale) > FLT_EPSILON) {
Scale.setValue(newScale);
}
}
updateChildrenScale();
}
if (prop == &Rotation) {
if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
Rotation.setValue(0.0);
purgeTouched();
Base::Console().Log("DPG: Projection Groups do not rotate. Change ignored.\n");
}
if (prop == &Rotation) {
if (!DrawUtil::fpCompare(Rotation.getValue(),0.0)) {
Rotation.setValue(0.0);
purgeTouched();
Base::Console().Log("DPG: Projection Groups do not rotate. Change ignored.\n");
}
return;
}
TechDraw::DrawViewCollection::onChanged(prop);
@@ -166,7 +177,8 @@ void DrawProjGroup::onChanged(const App::Property* prop)
App::DocumentObjectExecReturn *DrawProjGroup::execute()
{
// Base::Console().Message("DPG::execute() - %s\n", getNameInDocument());
// Base::Console().Message("DPG::execute() - %s - waitingForChildren: %d\n",
// getNameInDocument(), waitingForChildren());
if (!keepUpdated())
return App::DocumentObject::StdReturn;
@@ -178,15 +190,24 @@ App::DocumentObjectExecReturn *DrawProjGroup::execute()
//no anchor yet. nothing to do.
return DrawViewCollection::execute();
if (ScaleType.isValue("Automatic") && !checkFit()) {
m_lockScale = true;
Scale.setValue(autoScale());
Scale.purgeTouched();
updateChildrenScale();
m_lockScale = false;
if (waitingForChildren()) {
return DrawViewCollection::execute();
}
autoPositionChildren();
if (ScaleType.isValue("Automatic") && !checkFit()) {
if (!DrawUtil::fpCompare(getScale(), autoScale(), 0.00001)) {
Scale.setValue(autoScale());
//don't bother repositioning children since they will be
//recomputed at new scale
overrideKeepUpdated(false);
return DrawViewCollection::execute();
}
}
if (AutoDistribute.getValue()) {
autoPositionChildren();
}
overrideKeepUpdated(false);
return DrawViewCollection::execute();
}
@@ -211,37 +232,29 @@ short DrawProjGroup::mustExecute() const
return TechDraw::DrawViewCollection::mustExecute();
}
Base::BoundBox3d DrawProjGroup::getBoundingBox() const
void DrawProjGroup::reportReady()
{
Base::BoundBox3d bbox;
std::vector<App::DocumentObject*> views = Views.getValues();
TechDraw::DrawProjGroupItem *anchorView = dynamic_cast<TechDraw::DrawProjGroupItem *>(Anchor.getValue());
if (!anchorView) {
//if an element in Views is not a DPGI, something really bad has happened somewhere
Base::Console().Log("PROBLEM - DPG::getBoundingBox - non DPGI entry in Views! %s\n",
getNameInDocument());
throw Base::TypeError("Error: projection in DPG list is not a DPGI!");
// Base::Console().Message("DPG::reportReady - waitingForChildren: %d\n", waitingForChildren());
if (waitingForChildren()) {
//not ready yet
return;
}
for (std::vector<App::DocumentObject*>::const_iterator it = views.begin(); it != views.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(DrawViewPart::getClassTypeId())) {
DrawViewPart *part = static_cast<DrawViewPart *>(*it);
Base::BoundBox3d bb = part->getBoundingBox();
//all the secondary views are ready so we can now figure out alignment
if (AutoDistribute.getValue()) {
recomputeFeature();
}
}
bb.ScaleX(1. / part->getScale());
bb.ScaleY(1. / part->getScale());
bb.ScaleZ(1. / part->getScale());
// X and Y of dependent views are relative to the anchorView
if (part != anchorView) {
bb.MoveX(part->X.getValue());
bb.MoveY(part->Y.getValue());
}
bbox.Add(bb);
bool DrawProjGroup::waitingForChildren() const
{
for(const auto v : Views.getValues()) {
DrawProjGroupItem* dpgi = static_cast<DrawProjGroupItem*>(v);
if (dpgi->waitingForHlr() || //dpgi is still thinking
dpgi->isTouched()) { //dpgi needs to execute
return true;
}
}
return bbox;
return false;
}
TechDraw::DrawPage * DrawProjGroup::getPage() const
@@ -249,84 +262,92 @@ TechDraw::DrawPage * DrawProjGroup::getPage() const
return findParentPage();
}
// obs? replaced by autoscale?
// Function provided by Joe Dowsett, 2014
double DrawProjGroup::calculateAutomaticScale() const
//does the unscaled DPG fit on the page?
bool DrawProjGroup::checkFit() const
{
TechDraw::DrawPage *page = getPage();
// Base::Console().Message("DPG::checkFit() - %s\n", getNameInDocument());
if (waitingForChildren()) {
//assume everything fits since we don't know what size the chilren are
return true;
}
auto page = findParentPage();
if (!page)
throw Base::RuntimeError("No page is assigned to this feature");
DrawProjGroupItem *viewPtrs[10];
arrangeViewPointers(viewPtrs);
double width, height;
minimumBbViews(viewPtrs, width, height); //get SCALED boxes!
// if Page.keepUpdated is false, and DrawViews have never been executed,
// bb's will be 0x0 and this routine will return 0!!!
// if we return 1.0, AutoScale will sort itself out once bb's are non-zero.
double bbFudge = 1.2;
width *= bbFudge;
height *= bbFudge;
// C++ Standard says casting bool to int gives 0 or 1
int numVertSpaces = (viewPtrs[0] || viewPtrs[3] || viewPtrs[7]) +
(viewPtrs[2] || viewPtrs[5] || viewPtrs[9]) +
(viewPtrs[6] != nullptr);
int numHorizSpaces = (viewPtrs[0] || viewPtrs[1] || viewPtrs[2]) +
(viewPtrs[7] || viewPtrs[8] || viewPtrs[9]);
double availableX = page->getPageWidth();
double availableY = page->getPageHeight();
double xWhite = spacingX.getValue() * (numVertSpaces + 1);
double yWhite = spacingY.getValue() * (numHorizSpaces + 1);
width += xWhite;
height += yWhite;
double scale_x = availableX / width;
double scale_y = availableY / height;
double scaleFudge = 0.80;
float working_scale = scaleFudge * std::min(scale_x, scale_y);
double result = DrawUtil::sensibleScale(working_scale);
if (!(result > 0.0)) {
Base::Console().Log("DPG - %s - bad scale found (%.3f) using 1.0\n",getNameInDocument(),result);
result = 1.0;
}
return result;
return checkFit(page);
}
//returns the (scaled) bounding rectangle of all the views.
QRectF DrawProjGroup::getRect() const //this is current rect, not potential rect
bool DrawProjGroup::checkFit(DrawPage* page) const
{
// Base::Console().Message("DPG::checkFit(page) - %s\n", getNameInDocument());
if (waitingForChildren()) {
return true;
}
QRectF bigBox = getRect(false);
if ( (bigBox.width() <= page->getPageWidth()) &&
(bigBox.height() <= page->getPageHeight()) ) {
return true;
}
return false;
}
//calculate a scale that fits all views on page
double DrawProjGroup::autoScale() const
{
// Base::Console().Message("DPG::autoScale() - %s\n", getNameInDocument());
auto page = findParentPage();
if (!page) {
throw Base::RuntimeError("No page is assigned to this feature");
}
return autoScale(page->getPageWidth(), page->getPageHeight());
}
double DrawProjGroup::autoScale(double w, double h) const
{
// Base::Console().Message("DPG::autoScale(%.3f, %.3f) - %s\n", w, h, getNameInDocument());
//get the space used by views + white space at 1:1 scale
QRectF bigBox = getRect(false); //unscaled box
double xScale = w / bigBox.width(); // > 1 page bigger than figure
double yScale = h / bigBox.height(); // < 1 page is smaller than figure
double newScale = std::min(xScale,yScale);
return DrawUtil::sensibleScale(newScale);
}
//returns the bounding rectangle of all the views in the current scale
QRectF DrawProjGroup::getRect() const
{
return getRect(true);
}
QRectF DrawProjGroup::getRect(bool scaled) const
{
// Base::Console().Message("DPG::getRect - views: %d\n", Views.getValues().size());
DrawProjGroupItem *viewPtrs[10];
arrangeViewPointers(viewPtrs);
double width, height;
minimumBbViews(viewPtrs, width, height); //this is scaled!
double xSpace = spacingX.getValue() * 3.0 * std::max(1.0, getScale());
double ySpace = spacingY.getValue() * 2.0 * std::max(1.0, getScale());
double rectW = 0.0;
double rectH = 0.0;
if ( !(DrawUtil::fpCompare(width, 0.0) &&
DrawUtil::fpCompare(height, 0.0)) ) {
rectW = width + xSpace;
rectH = height + ySpace;
}
double fudge = 1.3; //make rect a little big to make sure it fits
double totalWidth, totalHeight;
getViewArea(viewPtrs, totalWidth, totalHeight, scaled);
double xSpace = spacingX.getValue() * 3.0;
double ySpace = spacingY.getValue() * 2.0;
double rectW = totalWidth + xSpace;
double rectH = totalHeight + ySpace;
double fudge = 1.2; //make rect a little big to make sure it fits
rectW *= fudge;
rectH *= fudge;
return QRectF(0,0,rectW,rectH);
}
//find area consumed by Views only in current scale
void DrawProjGroup::minimumBbViews(DrawProjGroupItem *viewPtrs[10],
double &width, double &height) const
//find area consumed by Views only - scaled or unscaled
void DrawProjGroup::getViewArea(DrawProjGroupItem *viewPtrs[10],
double &width, double &height,
bool scaled) const
{
// Get bounding boxes in object scale
// Get the child view bounding boxes
Base::BoundBox3d bboxes[10];
makeViewBbs(viewPtrs, bboxes, true); //true => scaled
makeViewBbs(viewPtrs, bboxes, scaled);
//TODO: note that TLF/TRF/BLF,BRF extend a bit farther than a strict row/col arrangement would suggest.
//get widest view in each row/column
double col0w = std::max(std::max(bboxes[0].LengthX(), bboxes[3].LengthX()), bboxes[7].LengthX()),
@@ -910,16 +931,16 @@ void DrawProjGroup::arrangeViewPointers(DrawProjGroupItem *viewPtrs[10]) const
void DrawProjGroup::makeViewBbs(DrawProjGroupItem *viewPtrs[10],
Base::BoundBox3d bboxes[10],
bool documentScale) const
bool scaled) const
{
Base::BoundBox3d empty(Base::Vector3d(0.0, 0.0, 0.0), 0.0);
for (int i = 0; i < 10; ++i) {
bboxes[i] = empty;
if (viewPtrs[i]) {
bboxes[i] = viewPtrs[i]->getBoundingBox();
// bboxes[i] = viewPtrs[i]->getBoundingBox(viewPtrs[i]->getProjectionCS(Base::Vector3d(0.0, 0.0, 0.0)));
if (!documentScale) {
if (!scaled) {
double scale = 1.0 / viewPtrs[i]->getScale(); //convert bbx to 1:1 scale
// double scale = 1.0 / viewPtrs[i]->getLastScale(); //convert bbx to 1:1 scale
bboxes[i].ScaleX(scale);
bboxes[i].ScaleY(scale);
bboxes[i].ScaleZ(scale);
@@ -930,7 +951,7 @@ void DrawProjGroup::makeViewBbs(DrawProjGroupItem *viewPtrs[10],
void DrawProjGroup::recomputeChildren()
{
// Base::Console().Message("DPG::recomputeChildren()\n");
// Base::Console().Message("DPG::recomputeChildren() - waiting: %d\n", waitingForChildren());
for( const auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
if (!view) {
@@ -943,14 +964,15 @@ void DrawProjGroup::recomputeChildren()
void DrawProjGroup::autoPositionChildren()
{
// Base::Console().Message("DPG::autoPositionChildren() - %s\n", getNameInDocument());
// Base::Console().Message("DPG::autoPositionChildren() - %s - waiting: %d\n",
// getNameInDocument(), waitingForChildren());
for( const auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
if (!view) {
//if an element in Views is not a DPGI, something really bad has happened somewhere
throw Base::TypeError("Error: projection in DPG list is not a DPGI!");
} else {
view->autoPosition();
view->requestPaint();
}
}
}
@@ -960,16 +982,16 @@ void DrawProjGroup::autoPositionChildren()
*/
void DrawProjGroup::updateChildrenScale()
{
// Base::Console().Message("DPG::updateChildrenScale\n");
// Base::Console().Message("DPG::updateChildrenScale() - waiting: %d\n", waitingForChildren());
for( const auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );
if (!view) {
//if an element in Views is not a DPGI, something really bad has happened somewhere
Base::Console().Log("PROBLEM - DPG::updateChildrenScale - non DPGI entry in Views! %s\n",
getNameInDocument());
throw Base::TypeError("Error: projection in DPG list is not a DPGI!");
} else {
view->Scale.setValue(getScale());
view->Scale.purgeTouched();
view->purgeTouched();
}
}
}
@@ -1016,22 +1038,7 @@ void DrawProjGroup::updateChildrenLock()
}
}
void DrawProjGroup::updateViews() {
// this is intended to update the views in general, e.g. when the spacing changed
for (const auto it : Views.getValues()) {
auto view(dynamic_cast<DrawProjGroupItem *>(it));
if (!view) {
//if an element in Views is not a DPGI, something really bad has happened somewhere
Base::Console().Log("PROBLEM - DPG::updateViews - non DPGI entry in Views! %s\n",
getNameInDocument());
throw Base::TypeError("Error: projection in DPG list is not a DPGI!");
}
else // the views are OK
view->recomputeFeature();
}
}
void DrawProjGroup::updateChildrenEnforce()
void DrawProjGroup::updateChildrenEnforce(void)
{
for( const auto it : Views.getValues() ) {
auto view( dynamic_cast<DrawProjGroupItem *>(it) );

View File

@@ -22,8 +22,8 @@
#ifndef _TECHDRAW_FEATUREVIEWGROUP_H_
#define _TECHDRAW_FEATUREVIEWGROUP_H_
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <string>
# include <QRectF>
@@ -51,7 +51,7 @@ class DrawProjGroupItem;
class TechDrawExport DrawProjGroup : public TechDraw::DrawViewCollection
{
PROPERTY_HEADER_WITH_OVERRIDE(TechDraw::DrawProjGroup);
Q_OBJECT
Q_OBJECT
public:
/// Constructor
@@ -72,9 +72,11 @@ public:
App::PropertyLink Anchor; /// Anchor Element to align views to
Base::BoundBox3d getBoundingBox() const;
double calculateAutomaticScale() const;
QRectF getRect() const override;
double autoScale() const override;
double autoScale(double w, double h) const override;
QRectF getRect() const override; //always scaled
QRectF getRect(bool scaled) const; //scaled or unscaled
/// Check if container has a view of a specific type
bool hasProjection(const char *viewProjType) const;
@@ -137,7 +139,13 @@ public:
void updateChildrenEnforce();
std::vector<App::DocumentObject*> getAllSources() const;
bool checkFit() const override;
bool checkFit(DrawPage* p) const override;
bool waitingForChildren() const;
void reportReady();
void dumpTouchedProps();
protected:
void onChanged(const App::Property* prop) override;
@@ -158,30 +166,29 @@ protected:
*/
void makeViewBbs(DrawProjGroupItem *viewPtrs[10],
Base::BoundBox3d bboxes[10],
bool documentScale = true) const;
bool scaled = true) const;
/// Helper for calculateAutomaticScale
/*!
* Returns a width and height in object-space scale, for the enabled views
* without accounting for their actual X and Y positions or borders.
*/
void minimumBbViews(DrawProjGroupItem *viewPtrs[10],
double &width, double &height) const;
void getViewArea(DrawProjGroupItem *viewPtrs[10],
double &width, double &height,
bool scaled = true) const;
/// Returns pointer to our page, or NULL if it couldn't be located
TechDraw::DrawPage * getPage() const;
void updateChildrenSource();
void updateChildrenLock();
void updateViews();
int getViewIndex(const char *viewTypeCStr) const;
int getDefProjConv() const;
Base::Vector3d dir2vec(gp_Dir d);
gp_Dir vec2dir(Base::Vector3d v);
void handleChangedPropertyType(Base::XMLReader &reader, const char *TypeName, App::Property * prop) override;
bool m_lockScale;
};
} //namespace TechDraw

View File

@@ -81,18 +81,7 @@ DrawProjGroupItem::~DrawProjGroupItem()
short DrawProjGroupItem::mustExecute() const
{
short result = 0;
if (!isRestoring()) {
result = (Direction.isTouched() ||
XDirection.isTouched() ||
Source.isTouched() ||
XSource.isTouched() ||
Scale.isTouched());
}
if (result) {
return result;
}
//there is nothing unique about dpgi vs dvp
return TechDraw::DrawViewPart::mustExecute();
}
@@ -158,22 +147,19 @@ App::DocumentObjectExecReturn *DrawProjGroupItem::execute(void)
return new App::DocumentObjectExecReturn("DPGI: Direction and XDirection are parallel");
}
App::DocumentObjectExecReturn* ret = DrawViewPart::execute();
//autoPosition needs to run after the geometry has been created
autoPosition();
return ret;
return DrawViewPart::execute();
}
void DrawProjGroupItem::postHlrTasks(void)
{
// Base::Console().Message("DPGI::postHlrTasks() - %s\n", getNameInDocument());
//DPGI has no geometry until HLR has finished, and the DPG can not properly
//AutoDistibute until all its items have geometry. autoPositionChildren is
//relatively cheap so we can do it after every geometry update
if (getPGroup() && getPGroup()->AutoDistribute.getValue()) {
getPGroup()->autoPositionChildren();
}
DrawViewPart::postHlrTasks();
//DPGI has no geometry until HLR has finished, and the DPG can not properly
//AutoDistibute until all its items have geometry.
autoPosition();
getPGroup()->reportReady(); //tell the parent DPG we are ready
}
void DrawProjGroupItem::autoPosition()
@@ -184,11 +170,12 @@ void DrawProjGroupItem::autoPosition()
}
Base::Vector3d newPos;
if (getPGroup() && getPGroup()->AutoDistribute.getValue()) {
newPos = getPGroup()->getXYPosition(Type.getValueAsString());
X.setValue(newPos.x);
Y.setValue(newPos.y);
requestPaint();
purgeTouched(); //prevents "still touched after recompute" message
newPos = getPGroup()->getXYPosition(Type.getValueAsString());
X.setValue(newPos.x);
Y.setValue(newPos.y);
requestPaint();
purgeTouched(); //prevents "still touched after recompute" message
getPGroup()->purgeTouched(); //changing dpgi x,y marks parent dpg as touched
}
}

View File

@@ -94,7 +94,8 @@ App::DocumentObjectExecReturn *DrawRichAnno::execute()
// Base::Console().Message("DRA::execute() - @ (%.3f, %.3f)\n", X.getValue(), Y.getValue());
if (!keepUpdated()) {
return App::DocumentObject::StdReturn;
}
}
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -74,7 +74,8 @@ PROPERTY_SOURCE(TechDraw::DrawView, App::DocumentObject)
DrawView::DrawView():
autoPos(true),
mouseMove(false)
mouseMove(false),
m_overrideKeepUpdated(false)
{
static const char *group = "Base";
ADD_PROPERTY_TYPE(X, (0.0), group, (App::PropertyType)(App::Prop_Output), "X position");
@@ -380,6 +381,7 @@ double DrawView::autoScale(double pw, double ph) const
bool DrawView::checkFit() const
{
// Base::Console().Message("DV::checkFit() - %s\n", getNameInDocument());
auto page = findParentPage();
return checkFit(page);
}
@@ -387,6 +389,7 @@ bool DrawView::checkFit() const
//!check if View is too big for page
bool DrawView::checkFit(TechDraw::DrawPage* p) const
{
// Base::Console().Message("DV::checkFit(page) - %s\n", getNameInDocument());
bool result = true;
double fudge = 1.1;
@@ -534,13 +537,14 @@ void DrawView::handleChangedPropertyType(
bool DrawView::keepUpdated()
{
// Base::Console().Message("DV::keepUpdated() - %s\n", getNameInDocument());
bool result = false;
if (overrideKeepUpdated()) {
return true;
}
TechDraw::DrawPage *page = findParentPage();
if(page) {
result = page->canUpdate() || page->forceRedraw();
return (page->canUpdate() || page->forceRedraw());
}
return result;
return false;
}
void DrawView::setScaleAttribute()

View File

@@ -112,6 +112,9 @@ public:
void setScaleAttribute();
void overrideKeepUpdated(bool s) { m_overrideKeepUpdated = s; }
bool overrideKeepUpdated(void) { return m_overrideKeepUpdated; }
protected:
void onChanged(const App::Property* prop) override;
virtual void validateScale();
@@ -125,6 +128,8 @@ protected:
private:
static const char* ScaleTypeEnums[];
static App::PropertyFloatConstraint::Constraints scaleRange;
bool m_overrideKeepUpdated;
};
typedef App::FeaturePythonT<DrawView> DrawViewPython;

View File

@@ -140,7 +140,7 @@ App::DocumentObjectExecReturn *DrawViewArch::execute()
Base::Interpreter().runStringArg("App.activeDocument().%s.Symbol = '%s' + svgBody + '%s'",
FeatName.c_str(),svgHead.c_str(),svgTail.c_str());
}
// requestPaint();
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -119,6 +119,7 @@ App::DocumentObjectExecReturn *DrawViewClip::execute()
}
requestPaint();
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -77,6 +77,7 @@ App::DocumentObjectExecReturn *DrawViewCollection::execute()
lockChildren();
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -24,35 +24,21 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
#include <Bnd_Box.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRep_Builder.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepPrim_Cylinder.hxx>
#include <BRepProj_Projection.hxx>
#include <BRepTools.hxx>
#include <Geom_Plane.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <HLRAlgo_Projector.hxx>
#include <HLRBRep_Algo.hxx>
#include <HLRBRep_HLRToShape.hxx>
#include <TopExp_Explorer.hxx>
#include <TopExp.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
@@ -61,42 +47,38 @@
#include <TopoDS_Shell.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#endif
#include <chrono>
#include <sstream>
#include <QFile>
#include <QFileInfo>
#include "QtConcurrent/qtconcurrentrun.h"
#include <QtConcurrentRun>
#include <App/Application.h>
#include <App/Document.h>
#include <App/Material.h>
#include <Base/BoundBox.h>
#include <Base/Exception.h>
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Parameter.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/TopoShape.h>
#include "Preferences.h"
#include "Geometry.h"
#include "GeometryObject.h"
#include "Cosmetic.h"
#include "EdgeWalker.h"
#include "DrawProjectSplit.h"
#include "DrawProjGroupItem.h"
#include "DrawPage.h"
#include "DrawUtil.h"
#include "DrawViewDetail.h"
#include "DrawViewSection.h"
#include "Geometry.h"
#include "GeometryObject.h"
#include "Preferences.h"
#include "DrawViewDetail.h"
using namespace TechDraw;
using namespace std;
//===========================================================================
// DrawViewDetail
//===========================================================================
@@ -104,7 +86,9 @@ using namespace std;
PROPERTY_SOURCE(TechDraw::DrawViewDetail, TechDraw::DrawViewPart)
DrawViewDetail::DrawViewDetail() :
m_waitingForDetail(false)
m_waitingForDetail(false),
m_saveDvp(nullptr),
m_saveDvs(nullptr)
{
static const char *dgroup = "Detail";
@@ -129,66 +113,71 @@ DrawViewDetail::~DrawViewDetail()
short DrawViewDetail::mustExecute() const
{
if (!isRestoring()) {
if (
AnchorPoint.isTouched() ||
Radius.isTouched() ||
BaseView.isTouched() ||
Reference.isTouched()
) {
return true;
}
if (isRestoring()) {
TechDraw::DrawView::mustExecute();
}
if (AnchorPoint.isTouched() ||
Radius.isTouched() ||
BaseView.isTouched() ||
Reference.isTouched()) {
return 1;
}
return TechDraw::DrawView::mustExecute();
}
void DrawViewDetail::onChanged(const App::Property* prop)
{
if (!isRestoring()) {
if (prop == &Reference) {
std::string lblText = "Detail " +
std::string(Reference.getValue());
Label.setValue(lblText);
}
if ((prop == &Reference) ||
(prop == &Radius) ||
(prop == &BaseView)) {
requestPaint();
}
if (prop == &AnchorPoint) {
// to see AnchorPoint changes repainting is not enough, we must recompute
recomputeFeature(true);
}
if (prop == &ScaleType) {
auto page = findParentPage();
// if ScaleType is "Page", the user cannot change it
if (ScaleType.isValue("Page")) {
Scale.setStatus(App::Property::ReadOnly, true);
// apply the page-wide Scale
if (page) {
if (std::abs(page->Scale.getValue() - getScale()) > FLT_EPSILON) {
Scale.setValue(page->Scale.getValue());
Scale.purgeTouched();
}
if (isRestoring()) {
DrawView::onChanged(prop);
return;
}
if (prop == &Reference) {
std::string lblText = "Detail " +
std::string(Reference.getValue());
Label.setValue(lblText);
}
if ((prop == &Reference) ||
(prop == &Radius) ||
(prop == &BaseView)) {
requestPaint();
}
if (prop == &AnchorPoint) {
// to see AnchorPoint changes repainting is not enough, we must recompute
recomputeFeature(true);
}
if (prop == &ScaleType) {
auto page = findParentPage();
// if ScaleType is "Page", the user cannot change it
if (ScaleType.isValue("Page")) {
Scale.setStatus(App::Property::ReadOnly, true);
// apply the page-wide Scale
if (page) {
if (std::abs(page->Scale.getValue() - getScale()) > FLT_EPSILON) {
Scale.setValue(page->Scale.getValue());
Scale.purgeTouched();
}
}
else if (ScaleType.isValue("Custom")) {
// allow the change Scale
Scale.setStatus(App::Property::ReadOnly, false);
}
else if (ScaleType.isValue("Automatic")) {
Scale.setStatus(App::Property::ReadOnly, true);
// apply a Scale
if (!checkFit(page)) {
double newScale = autoScale(page->getPageWidth(), page->getPageHeight());
if (std::abs(newScale - getScale()) > FLT_EPSILON) { //stops onChanged/execute loop
Scale.setValue(newScale);
Scale.purgeTouched();
}
}
else if (ScaleType.isValue("Custom")) {
// allow Scale changes
Scale.setStatus(App::Property::ReadOnly, false);
}
else if (ScaleType.isValue("Automatic")) {
Scale.setStatus(App::Property::ReadOnly, true);
// apply an automatic Scale
if (!checkFit(page)) {
double newScale = autoScale(page->getPageWidth(), page->getPageHeight());
if (std::abs(newScale - getScale()) > FLT_EPSILON) { //stops onChanged/execute loop
Scale.setValue(newScale);
Scale.purgeTouched();
}
}
}
}
DrawView::onChanged(prop);
}
@@ -196,19 +185,16 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
{
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
if (!keepUpdated()) {
return App::DocumentObject::StdReturn;
return DrawView::execute();
}
App::DocumentObject* baseObj = BaseView.getValue();
if (!baseObj) {
Base::Console().Log("DVD::execute - No BaseView(s) linked. - %s\n",
getNameInDocument());
return DrawView::execute();
}
if (!baseObj->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
Base::Console().Log("DVD::execute - %s - BaseView object is not a DrawViewPart object\n",
getNameInDocument());
//this can only happen via scripting?
return DrawView::execute();
}
@@ -224,8 +210,6 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
}
if (shape.IsNull()) {
Base::Console().Log("DVD::execute - %s - Source shape is Null\n",
getNameInDocument());
return DrawView::execute();
}
@@ -241,18 +225,7 @@ App::DocumentObjectExecReturn *DrawViewDetail::execute()
detailExec(shape, dvp, dvs);
addShapes2d();
//second pass if required
if (ScaleType.isValue("Automatic") && !checkFit()) {
double newScale = autoScale();
Scale.setValue(newScale);
Scale.purgeTouched();
if (geometryObject) {
delete geometryObject;
geometryObject = nullptr;
detailExec(shape, dvp, dvs);
}
}
dvp->requestPaint(); //to refresh detail highlight!
dvp->requestPaint(); //to refresh detail highlight in base view
return DrawView::execute();
}
@@ -262,93 +235,91 @@ void DrawViewDetail::detailExec(TopoDS_Shape& shape,
DrawViewPart* dvp,
DrawViewSection* dvs)
{
if (waitingForResult()) {
if (waitingForHlr() ||
waitingForDetail()) {
// Base::Console().Message("DVD::detailExec - waiting for result\n");
return;
}
if (waitingForDetail()) {
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);
waitingForDetail(true);
}
//this runs in a separate thread since it can sometimes take a long time
//make a common of the input shape and a cylinder (or prism depending on
//the matting style)
void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
DrawViewPart* dvp,
DrawViewSection* dvs)
{
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();
double radius = getFudgeRadius();
int solidCount = DrawUtil::countSubShapes(shape, TopAbs_SOLID);
int shellCount = DrawUtil::countSubShapes(shape, TopAbs_SHELL);
//make a copy of the input shape so we don't inadvertently change it
BRepBuilderAPI_Copy BuilderCopy(shape);
TopoDS_Shape myShape = BuilderCopy.Shape();
TopoDS_Shape copyShape = BuilderCopy.Shape();
m_saveShape = copyShape;
m_saveDvp = dvp;
m_saveDvs = dvs;
gp_Pnt gpCenter = TechDraw::findCentroid(myShape,
gp_Pnt gpCenter = TechDraw::findCentroid(copyShape,
dirDetail);
Base::Vector3d shapeCenter = Base::Vector3d(gpCenter.X(),gpCenter.Y(),gpCenter.Z());
m_saveCentroid = shapeCenter; //centroid of original shape
if (dvs) {
if (!dvs) {
//section cutShape should already be on origin
} else {
myShape = TechDraw::moveShape(myShape, //centre shape on origin
copyShape = TechDraw::moveShape(copyShape, //centre shape on origin
-shapeCenter);
}
shapeCenter = Base::Vector3d(0.0, 0.0, 0.0);
m_viewAxis = dvp->getProjectionCS(shapeCenter);
anchor = Base::Vector3d(anchor.x,anchor.y, 0.0); //anchor coord in projection CS
Base::Vector3d anchorOffset3d = DrawUtil::toR3(m_viewAxis, anchor); //actual anchor coords in R3
m_viewAxis = dvp->getProjectionCS(shapeCenter); //save the CS for later
Base::Vector3d anchor = AnchorPoint.getValue(); //this is a 2D point in unrotated base view coords
anchor = DrawUtil::toR3(m_viewAxis, anchor); //actual anchor coords in R3
Bnd_Box bbxSource;
bbxSource.SetGap(0.0);
BRepBndLib::AddOptimal(myShape, bbxSource);
BRepBndLib::AddOptimal(copyShape, bbxSource);
double diag = sqrt(bbxSource.SquareExtent());
Base::Vector3d toolPlaneOrigin = anchorOffset3d + dirDetail * diag * -1.0; //center tool about anchor
Base::Vector3d toolPlaneOrigin = anchor + dirDetail * diag * -1.0; //center tool about anchor
double extrudeLength = 2.0 * toolPlaneOrigin.Length();
gp_Pnt gpnt(toolPlaneOrigin.x,toolPlaneOrigin.y,toolPlaneOrigin.z);
gp_Dir gdir(dirDetail.x,dirDetail.y,dirDetail.z);
double hideToolRadius = radius * 1.0;
TopoDS_Face aProjFace;
TopoDS_Face extrusionFace;
Base::Vector3d extrudeVec = dirDetail * extrudeLength;
gp_Vec extrudeDir(extrudeVec.x,extrudeVec.y,extrudeVec.z);
gp_Vec extrudeDir(extrudeVec.x, extrudeVec.y, extrudeVec.z);
TopoDS_Shape tool;
if (Preferences::mattingStyle()) {
//square mat
gp_Pln gpln(gpnt,gdir);
BRepBuilderAPI_MakeFace mkFace(gpln, -hideToolRadius,hideToolRadius,-hideToolRadius,hideToolRadius);
aProjFace = mkFace.Face();
if(aProjFace.IsNull()) {
Base::Console().Warning("DVD::detailExec - %s - failed to create tool base face\n", getNameInDocument());
BRepBuilderAPI_MakeFace mkFace(gpln, -radius, radius, -radius, radius);
extrusionFace = mkFace.Face();
if(extrusionFace.IsNull()) {
Base::Console().Warning("DVD::makeDetailShape - %s - failed to create tool base face\n", getNameInDocument());
return;
}
tool = BRepPrimAPI_MakePrism(aProjFace, extrudeDir, false, true).Shape();
tool = BRepPrimAPI_MakePrism(extrusionFace, extrudeDir, false, true).Shape();
if(tool.IsNull()) {
Base::Console().Warning("DVD::detailExec - %s - failed to create tool (prism)\n", getNameInDocument());
Base::Console().Warning("DVD::makeDetailShape - %s - failed to create tool (prism)\n", getNameInDocument());
return;
}
} else {
//circular mat
gp_Ax2 cs(gpnt, gdir);
BRepPrimAPI_MakeCylinder mkTool(cs, hideToolRadius, extrudeLength);
BRepPrimAPI_MakeCylinder mkTool(cs, radius, extrudeLength);
tool = mkTool.Shape();
if(tool.IsNull()) {
Base::Console().Warning("DVD::detailExec - %s - failed to create tool (cylinder)\n", getNameInDocument());
@@ -356,29 +327,29 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
}
}
//for each solid and shell in the input shape, make a common with the tool and
//add the result to a compound. This avoids issues with some geometry errors in the
//input shape.
BRep_Builder builder;
TopoDS_Compound pieces;
builder.MakeCompound(pieces);
if (solidCount > 0) {
TopExp_Explorer expl(myShape, TopAbs_SOLID);
TopExp_Explorer expl(copyShape, TopAbs_SOLID);
for (; expl.More(); expl.Next()) {
const TopoDS_Solid& s = TopoDS::Solid(expl.Current());
BRepAlgoAPI_Common mkCommon(s,tool);
if (!mkCommon.IsDone()) {
// Base::Console().Warning("DVD::execute - %s - detail cut operation failed (1)\n", getNameInDocument());
continue;
}
if (mkCommon.Shape().IsNull()) {
// Base::Console().Warning("DVD::execute - %s - detail cut operation failed (2)\n", getNameInDocument());
continue;
}
//this might be overkill for piecewise algo
//Did we get at least 1 solid?
TopExp_Explorer xp;
xp.Init(mkCommon.Shape(),TopAbs_SOLID);
if (!(xp.More() == Standard_True)) {
// Base::Console().Warning("DVD::execute - mkCommon.Shape is not a solid!\n");
if ((xp.More() != Standard_True)) {
continue;
}
builder.Add(pieces, mkCommon.Shape());
@@ -386,25 +357,22 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
}
if (shellCount > 0) {
TopExp_Explorer expl(myShape, TopAbs_SHELL);
TopExp_Explorer expl(copyShape, TopAbs_SHELL);
for (; expl.More(); expl.Next()) {
const TopoDS_Shell& s = TopoDS::Shell(expl.Current());
BRepAlgoAPI_Common mkCommon(s,tool);
if (!mkCommon.IsDone()) {
// Base::Console().Warning("DVD::execute - %s - detail cut operation failed (1)\n", getNameInDocument());
continue;
}
if (mkCommon.Shape().IsNull()) {
// Base::Console().Warning("DVD::execute - %s - detail cut operation failed (2)\n", getNameInDocument());
continue;
}
//this might be overkill for piecewise algo
//Did we get at least 1 shell?
TopExp_Explorer xp;
xp.Init(mkCommon.Shape(),TopAbs_SHELL);
if (!(xp.More() == Standard_True)) {
// Base::Console().Warning("DVD::execute - mkCommon.Shape is not a shell!\n");
if ((xp.More() != Standard_True)) {
continue;
}
builder.Add(pieces, mkCommon.Shape());
@@ -413,17 +381,10 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
if (debugDetail()) {
BRepTools::Write(tool, "DVDTool.brep"); //debug
BRepTools::Write(myShape, "DVDCopy.brep"); //debug
BRepTools::Write(copyShape, "DVDCopy.brep"); //debug
BRepTools::Write(pieces, "DVDCommon.brep"); //debug
}
//for debugging show compound instead of common
// BRep_Builder builder;
// TopoDS_Compound Comp;
// builder.MakeCompound(Comp);
// builder.Add(Comp, tool);
// builder.Add(Comp, myShape);
gp_Pnt inputCenter;
try {
//centroid of result
@@ -438,7 +399,7 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
(shellCount > 0)) {
//align shape with detail anchor
TopoDS_Shape centeredShape = TechDraw::moveShape(pieces,
anchorOffset3d * -1.0);
anchor * -1.0);
m_scaledShape = TechDraw::scaleShape(centeredShape,
getScale());
if (debugDetail()) {
@@ -446,9 +407,9 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
}
} else {
//no solids, no shells, do what you can with edges
TopoDS_Shape projectedEdges = projectEdgesOntoFace(myShape, aProjFace, gdir);
TopoDS_Shape projectedEdges = projectEdgesOntoFace(copyShape, extrusionFace, gdir);
TopoDS_Shape centeredShape = TechDraw::moveShape(projectedEdges,
anchorOffset3d * -1.0);
anchor * -1.0);
if (debugDetail()) {
BRepTools::Write(projectedEdges, "DVDProjectedEdges.brep"); //debug
BRepTools::Write(centeredShape, "DVDCenteredShape.brep"); //debug
@@ -472,10 +433,6 @@ void DrawViewDetail::makeDetailShape(TopoDS_Shape& shape,
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");
}
@@ -485,6 +442,19 @@ void DrawViewDetail::postHlrTasks(void)
geometryObject->pruneVertexGeom(Base::Vector3d(0.0,0.0,0.0),
Radius.getValue() * getScale()); //remove vertices beyond clipradius
DrawViewPart::postHlrTasks();
//second pass if required
if (ScaleType.isValue("Automatic") && !checkFit()) {
double newScale = autoScale();
Scale.setValue(newScale);
Scale.purgeTouched();
if (geometryObject) {
delete geometryObject;
geometryObject = nullptr;
detailExec(m_saveShape, m_saveDvp, m_saveDvs);
}
}
overrideKeepUpdated(false);
}
//continue processing after makeDetailShape thread is finished
@@ -497,6 +467,15 @@ void DrawViewDetail::onMakeDetailFinished(void)
geometryObject = buildGeometryObject(m_scaledShape, m_viewAxis);
}
bool DrawViewDetail::waitingForResult() const
{
if (DrawViewPart::waitingForResult() ||
waitingForDetail()) {
return true;
}
return false;
}
TopoDS_Shape DrawViewDetail::projectEdgesOntoFace(TopoDS_Shape &edgeShape,
TopoDS_Face &projFace,
gp_Dir& projDir)

View File

@@ -81,7 +81,8 @@ public:
DrawViewSection* dvs);
void postHlrTasks(void) override;
void waitingForDetail(bool s) { m_waitingForDetail = s; }
bool waitingForDetail(void) { return m_waitingForDetail; }
bool waitingForDetail(void) const { return m_waitingForDetail; }
bool waitingForResult() const override;
double getFudgeRadius(void);
TopoDS_Shape projectEdgesOntoFace(TopoDS_Shape& edgeShape,
@@ -104,6 +105,9 @@ protected:
QFutureWatcher<void> m_detailWatcher;
QFuture<void> m_detailFuture;
bool m_waitingForDetail;
DrawViewPart* m_saveDvp;
DrawViewSection* m_saveDvs;
};
typedef App::FeaturePythonT<DrawViewDetail> DrawViewDetailPython;

View File

@@ -133,7 +133,7 @@ App::DocumentObjectExecReturn *DrawViewDimExtent::execute(void)
TechDraw::VertexPtr v0 = dvp->getProjVertexByCosTag(cTags[0]);
TechDraw::VertexPtr v1 = dvp->getProjVertexByCosTag(cTags[1]);
if (!v0 || v1)
if (!v0 || !v1)
return DrawViewDimension::execute();
double length00 = (v0->pnt - refMin).Length();
@@ -156,6 +156,7 @@ App::DocumentObjectExecReturn *DrawViewDimExtent::execute(void)
cvTemp->permaPoint = refMax / scale;
}
overrideKeepUpdated(false);
return DrawViewDimension::execute();
}

View File

@@ -736,7 +736,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute()
m_hasGeometry = true;
}
//TODO: if MeasureType = Projected and the Projected shape changes, the Dimension may become invalid (see tilted Cube example)
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -126,7 +126,8 @@ App::DocumentObjectExecReturn *DrawViewDraft::execute()
Base::Interpreter().runStringArg("App.activeDocument().%s.Symbol = '%s' + svgBody + '%s'",
FeatName.c_str(),svgHead.c_str(),svgTail.c_str());
}
// requestPaint();
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -111,7 +111,7 @@ QRectF DrawViewImage::getRect() const
void DrawViewImage::replaceImageIncluded(std::string newFileName)
{
Base::Console().Message("DVI::replaceImageIncluded(%s)\n", newFileName.c_str());
// Base::Console().Message("DVI::replaceImageIncluded(%s)\n", newFileName.c_str());
if (ImageIncluded.isEmpty()) {
setupImageIncluded();
} else {
@@ -123,7 +123,7 @@ void DrawViewImage::replaceImageIncluded(std::string newFileName)
void DrawViewImage::setupImageIncluded()
{
Base::Console().Message("DVI::setupImageIncluded()\n");
// Base::Console().Message("DVI::setupImageIncluded()\n");
App::Document* doc = getDocument();
std::string dir = doc->TransientDir.getValue();
std::string special = getNameInDocument();

View File

@@ -26,60 +26,36 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
#include "QtConcurrent/qtconcurrentrun.h"
#include <Bnd_Box.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepAlgo_NormalProjection.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRep_Builder.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepGProp.hxx>
#include <BRepLib.hxx>
#include <BRepLProp_CLProps.hxx>
#include <BRepLProp_CurveTool.hxx>
#include <BRep_Tool.hxx>
#include <BRepTools.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <Geom_Curve.hxx>
#include <GeomLib_Tool.hxx>
#include <gp_Ax2.hxx>
#include <gp_Dir.hxx>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <GProp_GProps.hxx>
#include <gp_XYZ.hxx>
#include <HLRAlgo_Projector.hxx>
#include <HLRBRep_Algo.hxx>
#include <HLRBRep_HLRToShape.hxx>
#include <HLRBRep_ShapeBounds.hxx>
#include <ShapeExtend_WireData.hxx>
#include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Wire.hxx>
#include <TopExp_Explorer.hxx>
#include <TopExp.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <BRepAlgo_NormalProjection.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#endif
#include <limits>
#include <algorithm>
#include <cmath>
#include <sstream>
#include <QtConcurrentRun>
#include <App/Application.h>
#include <App/Document.h>
@@ -90,11 +66,11 @@
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Parameter.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/Part/App/PropertyTopoShape.h>
#include "Preferences.h"
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Part/App/PropertyTopoShape.h>
#include <Mod/Part/App/TopoShape.h>
#include "Cosmetic.h"
#include "DrawGeomHatch.h"
#include "DrawHatch.h"
@@ -104,15 +80,16 @@
#include "DrawViewBalloon.h"
#include "DrawViewDetail.h"
#include "DrawViewDimension.h"
#include "LandmarkDimension.h"
#include "DrawViewPart.h"
#include "DrawViewSection.h"
#include "EdgeWalker.h"
#include "Geometry.h"
#include "GeometryObject.h"
#include "LandmarkDimension.h"
#include "LineGroup.h"
#include "Preferences.h"
#include "ShapeExtractor.h"
#include "DrawViewPart.h"
#include <Mod/TechDraw/App/DrawViewPartPy.h> // generated from DrawViewPartPy.xml
using namespace TechDraw;
@@ -160,10 +137,9 @@ DrawViewPart::DrawViewPart(void) :
"Perspective(true) or Orthographic(false) projection");
ADD_PROPERTY_TYPE(Focus,(defDist),group,App::Prop_None,"Perspective view focus distance");
//properties that control HLR algoaffect Appearance
//properties that control HLR algo
bool coarseView = hGrp->GetBool("CoarseView", false);
ADD_PROPERTY_TYPE(CoarseView, (coarseView), sgroup, App::Prop_None, "Coarse View on/off");
//add property for visible outline?
ADD_PROPERTY_TYPE(SmoothVisible ,(prefSmoothViz()),sgroup,App::Prop_None,"Show Visible Smooth lines");
ADD_PROPERTY_TYPE(SeamVisible ,(prefSeamViz()),sgroup,App::Prop_None,"Show Visible Seam lines");
ADD_PROPERTY_TYPE(IsoVisible ,(prefIsoViz()),sgroup,App::Prop_None,"Show Visible Iso u,v lines");
@@ -173,7 +149,6 @@ DrawViewPart::DrawViewPart(void) :
ADD_PROPERTY_TYPE(IsoHidden ,(prefIsoHid()),sgroup,App::Prop_None,"Show Hidden Iso u,v lines");
ADD_PROPERTY_TYPE(IsoCount ,(prefIsoCount()),sgroup,App::Prop_None,"Number of iso parameters lines");
geometryObject = nullptr;
//initialize bbox to non-garbage
bbox = Base::BoundBox3d(Base::Vector3d(0.0, 0.0, 0.0), 0.0);
}
@@ -193,55 +168,31 @@ std::vector<TopoDS_Shape> DrawViewPart::getSourceShape2d() const
return result;
}
TopoDS_Shape DrawViewPart::getSourceShape() const
{
// Base::Console().Message("DVP::getSourceShape()\n");
TopoDS_Shape result;
const std::vector<App::DocumentObject*>& links = getAllSources();
if (links.empty()) {
bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring);
if (isRestoring) {
Base::Console().Warning("DVP::getSourceShape - No Sources (but document is restoring) - %s\n",
getNameInDocument());
} else {
Base::Console().Error("Error: DVP::getSourceShape - No Source(s) linked. - %s\n",
getNameInDocument());
}
} else {
result = ShapeExtractor::getShapes(links);
if (!links.empty()) {
return ShapeExtractor::getShapes(links);
}
return result;
return TopoDS_Shape();
}
TopoDS_Shape DrawViewPart::getSourceShapeFused() const
{
// Base::Console().Message("DVP::getSourceShapeFused()\n");
TopoDS_Shape result;
// const std::vector<App::DocumentObject*>& links = Source.getValues();
const std::vector<App::DocumentObject*>& links = getAllSources();
if (links.empty()) {
bool isRestoring = getDocument()->testStatus(App::Document::Status::Restoring);
if (isRestoring) {
Base::Console().Warning("DVP::getSourceShape - No Sources (but document is restoring) - %s\n",
getNameInDocument());
} else {
Base::Console().Error("Error: DVP::getSourceShape - No Source(s) linked. - %s\n",
getNameInDocument());
}
} else {
result = ShapeExtractor::getShapesFused(links);
if (!links.empty()) {
return ShapeExtractor::getShapesFused(links);
}
return result;
return TopoDS_Shape();
}
std::vector<App::DocumentObject*> DrawViewPart::getAllSources() const
{
// Base::Console().Message("DVP::getAllSources()\n");
const std::vector<App::DocumentObject*> links = Source.getValues();
std::vector<App::DocumentObject*> links = Source.getValues();
std::vector<DocumentObject*> xLinks = XSource.getValues();
// std::vector<DocumentObject*> xLinks;
// XSource.getLinks(xLinks);
std::vector<App::DocumentObject*> result = links;
if (!xLinks.empty()) {
@@ -250,6 +201,8 @@ std::vector<App::DocumentObject*> DrawViewPart::getAllSources() const
return result;
}
//pick supported 2d shapes out of the Source properties and
//add them directly to the geometry without going through HLR
void DrawViewPart::addShapes2d(void)
{
std::vector<TopoDS_Shape> shapes = getSourceShape2d();
@@ -285,20 +238,13 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
// Base::Console().Message("DVP::execute() - %s\n", getNameInDocument());
if (!keepUpdated()) {
return App::DocumentObject::StdReturn;
return DrawView::execute();
}
if (waitingForResult()) {
if (waitingForHlr()) {
return DrawView::execute();
}
const std::vector<App::DocumentObject*>& links = getAllSources();
if (links.empty()) {
Base::Console().Log("DVP::execute - %s - No Source(s) linked.\n",
getNameInDocument());
return DrawView::execute();
}
TopoDS_Shape shape = getSourceShape();
if (shape.IsNull()) {
Base::Console().Log("DVP::execute - %s - Source shape is Null.\n",
@@ -306,58 +252,46 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
return DrawView::execute();
}
//make sure the XDirection property is valid. Mostly for older models.
if (!checkXDirection()) {
//block touch/onChanged stuff
Base::Vector3d newX = getXDirection();
XDirection.setValue(newX);
XDirection.purgeTouched(); //don't trigger updates!
//unblock
}
m_saveShape = shape;
partExec(shape);
addShapes2d();
//second pass if required
if (ScaleType.isValue("Automatic")) {
if (!checkFit()) {
double newScale = autoScale();
Scale.setValue(newScale);
Scale.purgeTouched();
partExec(shape);
}
}
return DrawView::execute();
}
short DrawViewPart::mustExecute() const
{
short result = 0;
if (!isRestoring()) {
result = (Direction.isTouched() ||
Source.isTouched() ||
XSource.isTouched() ||
Perspective.isTouched() ||
Focus.isTouched() ||
Rotation.isTouched() ||
SmoothVisible.isTouched() ||
SeamVisible.isTouched() ||
IsoVisible.isTouched() ||
HardHidden.isTouched() ||
SmoothHidden.isTouched() ||
SeamHidden.isTouched() ||
IsoHidden.isTouched() ||
IsoCount.isTouched() ||
CoarseView.isTouched() ||
CosmeticVertexes.isTouched() ||
CosmeticEdges.isTouched() ||
CenterLines.isTouched());
if (isRestoring()) {
return TechDraw::DrawView::mustExecute();
}
if (result) {
return result;
if (Direction.isTouched() ||
Source.isTouched() ||
XSource.isTouched() ||
Perspective.isTouched() ||
Focus.isTouched() ||
Rotation.isTouched() ||
SmoothVisible.isTouched() ||
SeamVisible.isTouched() ||
IsoVisible.isTouched() ||
HardHidden.isTouched() ||
SmoothHidden.isTouched() ||
SeamHidden.isTouched() ||
IsoHidden.isTouched() ||
IsoCount.isTouched() ||
CoarseView.isTouched() ||
CosmeticVertexes.isTouched() ||
CosmeticEdges.isTouched() ||
CenterLines.isTouched()) {
return 1;
}
return TechDraw::DrawView::mustExecute();
}
@@ -377,8 +311,7 @@ void DrawViewPart::partExec(TopoDS_Shape& shape)
{
// Base::Console().Message("DVP::partExec()\n");
if (waitingForHlr()) {
//finish what we are already doing before starting over
// Base::Console().Message("DVP::partExec - %s - waiting for HLR\n", getNameInDocument());
//finish what we are already doing before starting a new cycle
return;
}
@@ -386,13 +319,18 @@ void DrawViewPart::partExec(TopoDS_Shape& shape)
delete geometryObject;
geometryObject = nullptr;
}
geometryObject = makeGeometryForShape(shape);
if (CoarseView.getValue()){
onHlrFinished(); //poly algo does not run in separate thread, so we need to invoke
//the post hlr processing manually
}
}
//prepare the shape for HLR processing by centering, scaling and rotating it
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);
@@ -420,11 +358,12 @@ GeometryObject* DrawViewPart::makeGeometryForShape(TopoDS_Shape& shape)
return go;
}
//note: slightly different than routine with same name in DrawProjectSplit
//create a geometry object and trigger the HLR process in another thread
TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape, gp_Ax2& viewAxis)
{
// Base::Console().Message("DVP::buildGeometryObject() - %s\n", getNameInDocument());
showProgressMessage(getNameInDocument(), "is finding hidden lines");
TechDraw::GeometryObject* go = new TechDraw::GeometryObject(getNameInDocument(), this);
go->setIsoCount(IsoCount.getValue());
go->isPerspective(Perspective.getValue());
@@ -432,12 +371,12 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape,
go->usePolygonHLR(CoarseView.getValue());
if (CoarseView.getValue()){
//the polygon approximation HLR process runs quickly, so doesn't need to be in a
//separate thread
go->projectShapeWithPolygonAlgo(shape,
viewAxis);
onHlrFinished(); //poly algo does not run in separate thread, so we need to invoke
//the post hlr processing manually
} else {
//project shape runs in a separate thread since if can take a long time
//projectShape (the HLR process) runs in a separate thread since it 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);
@@ -450,21 +389,23 @@ TechDraw::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape& shape,
void DrawViewPart::onHlrFinished(void)
{
// Base::Console().Message("DVP::onHlrFinished() - %s\n", getNameInDocument());
//the last hlr task is to make a bbox of the results
//the last hlr related task is to make a bbox of the results
bbox = geometryObject->calcBoundingBox();
waitingForHlr(false);
QObject::disconnect(&m_hlrWatcher, SIGNAL(finished()), this, SLOT(onHlrFinished()));
showProgressMessage(getNameInDocument(), "has finished finding hidden lines");
postHlrTasks();
postHlrTasks(); //application level tasks that depend on HLR/GO being complete
//start face finding in a separate thread
//start face finding in a separate thread. We don't find faces when using the polygon
//HLR method
if (handleFaces() && !CoarseView.getValue() && !waitingForFaces()) {
try {
QObject::connect(&m_faceWatcher, SIGNAL(finished()), this, SLOT(onFacesFinished()));
m_faceFuture = QtConcurrent::run(this, &DrawViewPart::extractFaces);
m_faceWatcher.setFuture(m_faceFuture);
waitingForFaces(true);
}
catch (Standard_Failure& e) {
waitingForFaces(false);
@@ -483,6 +424,7 @@ void DrawViewPart::postHlrTasks(void)
addCosmeticEdgesToGeom();
addCenterLinesToGeom();
addReferencesToGeom();
addShapes2d();
//dimensions and balloons need to be recomputed here because their
//references will be invalid until the geometry exists
@@ -495,42 +437,49 @@ void DrawViewPart::postHlrTasks(void)
b->recomputeFeature();
}
//second pass if required
if (ScaleType.isValue("Automatic")) {
if (!checkFit()) {
double newScale = autoScale();
Scale.setValue(newScale);
Scale.purgeTouched();
partExec(m_saveShape);
}
}
overrideKeepUpdated(false);
requestPaint();
}
//! make faces from the existing edge geometry
//! make faces from the edge geometry
void DrawViewPart::extractFaces()
{
// Base::Console().Message("DVP::extractFaces()\n");
if (!geometryObject) {
if (!geometryObject ||
!this->hasGeometry()) {
//no geometry yet so don't bother
return;
}
waitingForFaces(true);
showProgressMessage(getNameInDocument(), "is extracting faces");
geometryObject->clearFaceGeom();
const std::vector<TechDraw::BaseGeomPtr>& goEdges =
geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue());
std::vector<TechDraw::BaseGeomPtr>::const_iterator itEdge = goEdges.begin();
//make a copy of the input edges so the loose tolerances of face finding are
//not applied to the real edge geometry. See TopoDS_Shape::TShape().
std::vector<TopoDS_Edge> copyEdges;
for (;itEdge != goEdges.end(); itEdge++) {
BRepBuilderAPI_Copy copier((*itEdge)->occEdge, true, true);
for (auto& tdEdge: goEdges) {
BRepBuilderAPI_Copy copier(tdEdge->occEdge, true, true); //copy occEdge with its geometry (TShape) and mesh info
copyEdges.push_back(TopoDS::Edge(copier.Shape()));
}
std::vector<TopoDS_Edge> faceEdges;
std::vector<TopoDS_Edge> nonZero;
for (auto& e:copyEdges) { //drop any zero edges (shouldn't be any by now!!!)
if (!DrawUtil::isZeroEdge(e)) {
nonZero.push_back(e);
} else {
Base::Console().Log("INFO - DVP::extractFaces for %s found ZeroEdge!\n",getNameInDocument());
}
}
@@ -539,18 +488,16 @@ void DrawViewPart::extractFaces()
std::vector<splitPoint> splits;
std::vector<TopoDS_Edge>::iterator itOuter = nonZero.begin();
int iOuter = 0;
for (; itOuter != nonZero.end(); ++itOuter, iOuter++) { //*** itOuter != nonZero.end() - 1
for (; itOuter != nonZero.end(); ++itOuter, iOuter++) {
TopoDS_Vertex v1 = TopExp::FirstVertex((*itOuter));
TopoDS_Vertex v2 = TopExp::LastVertex((*itOuter));
Bnd_Box sOuter;
BRepBndLib::AddOptimal(*itOuter, sOuter);
sOuter.SetGap(0.1);
if (sOuter.IsVoid()) {
Base::Console().Log("DVP::Extract Faces - outer Bnd_Box is void for %s\n",getNameInDocument());
continue;
}
if (DrawUtil::isZeroEdge(*itOuter)) {
Base::Console().Log("DVP::extractFaces - outerEdge: %d is ZeroEdge\n",iOuter); //this is not finding ZeroEdges
continue; //skip zero length edges. shouldn't happen ;)
}
int iInner = 0;
@@ -567,14 +514,13 @@ void DrawViewPart::extractFaces()
BRepBndLib::AddOptimal(*itInner, sInner);
sInner.SetGap(0.1);
if (sInner.IsVoid()) {
Base::Console().Log("INFO - DVP::Extract Faces - inner Bnd_Box is void for %s\n",getNameInDocument());
continue;
}
if (sOuter.IsOut(sInner)) { //bboxes of edges don't intersect, don't bother
continue;
}
double param = -1;
double param = -1; //parametric point on edge where the vertex touches
if (DrawProjectSplit::isOnEdge((*itInner),v1,param,false)) {
gp_Pnt pnt1 = BRep_Tool::Pnt(v1);
splitPoint s1;
@@ -594,17 +540,20 @@ void DrawViewPart::extractFaces()
} //inner loop
} //outer loop
//if edge A was touched at the same point by multiple edges B, we only want to split A once
std::vector<splitPoint> sorted = DrawProjectSplit::sortSplits(splits,true);
auto last = std::unique(sorted.begin(), sorted.end(), DrawProjectSplit::splitEqual); //duplicates to back
sorted.erase(last, sorted.end()); //remove dupl splits
sorted.erase(last, sorted.end()); //remove duplicate splits
std::vector<TopoDS_Edge> newEdges = DrawProjectSplit::splitEdges(nonZero,sorted);
if (newEdges.empty()) {
Base::Console().Log("DVP::extractFaces - no newEdges\n");
Base::Console().Log("DVP::extractFaces - no edges return by splitting process\n");
waitingForFaces(false);
return;
}
//try to remove any duplicated edges since they will confuse the edgeWalker
newEdges = DrawProjectSplit::removeDuplicateEdges(newEdges);
//find all the wires in the pile of faceEdges
@@ -612,7 +561,7 @@ void DrawViewPart::extractFaces()
ew.loadEdges(newEdges);
bool success = ew.perform();
if (!success) {
Base::Console().Warning("DVP::extractFaces - %s -Can't make faces from projected edges\n", getNameInDocument());
Base::Console().Warning("DVP::extractFaces - %s - Can't make faces from projected edges\n", getNameInDocument());
waitingForFaces(false);
return;
}
@@ -620,23 +569,19 @@ void DrawViewPart::extractFaces()
std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(fw,true);
// int idb = 0;
std::vector<TopoDS_Wire>::iterator itWire = sortedWires.begin();
for (; itWire != sortedWires.end(); itWire++) {
//version 1: 1 wire/face - no voids in face
//debug
// std::stringstream ss;
// ss << "DVPSWire" << idb << ".brep";
// std::string wireName = ss.str();
// BRepTools::Write((*itWire), wireName.c_str()); //debug
//debug idb++;
TechDraw::FacePtr f(std::make_shared<TechDraw::Face>());
const TopoDS_Wire& wire = (*itWire);
TechDraw::Wire* w = new TechDraw::Wire(wire);
f->wires.push_back(w);
geometryObject->addFaceGeom(f);
if (geometryObject) {
//it can happen that a new hlr cycle deletes geometryObject while we are
//extracting faces. if it does happen, a new cycle should fix it.
geometryObject->addFaceGeom(f);
}
}
waitingForFaces(false);
}
//continue processing after extractFaces thread completes
@@ -649,28 +594,30 @@ void DrawViewPart::onFacesFinished(void)
requestPaint();
}
//retrieve all the face hatches associated with this dvp
std::vector<TechDraw::DrawHatch*> DrawViewPart::getHatches() const
{
std::vector<TechDraw::DrawHatch*> result;
std::vector<App::DocumentObject*> children = getInList();
for (std::vector<App::DocumentObject*>::iterator it = children.begin(); it != children.end(); ++it) {
if ( ((*it)->getTypeId().isDerivedFrom(DrawHatch::getClassTypeId())) &&
(!(*it)->isRemoving()) ) {
TechDraw::DrawHatch* hatch = dynamic_cast<TechDraw::DrawHatch*>(*it);
for (auto& child: children) {
if ( (child->getTypeId().isDerivedFrom(DrawHatch::getClassTypeId())) &&
(!child->isRemoving()) ) {
TechDraw::DrawHatch* hatch = dynamic_cast<TechDraw::DrawHatch*>(child);
result.push_back(hatch);
}
}
return result;
}
//retrieve all the geometric hatches associated with this dvp
std::vector<TechDraw::DrawGeomHatch*> DrawViewPart::getGeomHatches() const
{
std::vector<TechDraw::DrawGeomHatch*> result;
std::vector<App::DocumentObject*> children = getInList();
for (std::vector<App::DocumentObject*>::iterator it = children.begin(); it != children.end(); ++it) {
if ( ((*it)->getTypeId().isDerivedFrom(DrawGeomHatch::getClassTypeId())) &&
(!(*it)->isRemoving()) ) {
TechDraw::DrawGeomHatch* geom = dynamic_cast<TechDraw::DrawGeomHatch*>(*it);
for (auto& child: children) {
if ( (child->getTypeId().isDerivedFrom(DrawGeomHatch::getClassTypeId())) &&
(!child->isRemoving()) ) {
TechDraw::DrawGeomHatch* geom = dynamic_cast<TechDraw::DrawGeomHatch*>(child);
result.push_back(geom);
}
}
@@ -678,6 +625,8 @@ std::vector<TechDraw::DrawGeomHatch*> DrawViewPart::getGeomHatches() const
}
//return *unique* list of Dimensions which reference this DVP
//if the dimension has two references to this dvp, it will appear twice in
//the inlist
std::vector<TechDraw::DrawViewDimension*> DrawViewPart::getDimensions() const
{
std::vector<TechDraw::DrawViewDimension*> result;
@@ -892,35 +841,31 @@ BaseGeomPtr DrawViewPart::projectEdge(const TopoDS_Edge& e) const
bool DrawViewPart::waitingForResult() const
{
bool result(false);
if (waitingForHlr()) {
result = true;
if (waitingForHlr() ||
waitingForFaces()) {
return true;
}
// if (waitingForFaces()) {
// result = true;
// }
return result;
return false;
}
bool DrawViewPart::hasGeometry(void) const
{
bool result = false;
if (!geometryObject) {
return result;
return false;
}
if (waitingForResult()) {
return result;
if (waitingForHlr()) {
return false;
}
const std::vector<TechDraw::VertexPtr> &verts = getVertexGeometry();
const std::vector<TechDraw::BaseGeomPtr> &edges = getEdgeGeometry();
if (verts.empty() &&
edges.empty() ) {
result = false;
return false;
} else {
result = true;
return true;
}
return result;
return false;
}
gp_Ax2 DrawViewPart::getProjectionCS(const Base::Vector3d pt) const

View File

@@ -209,7 +209,7 @@ public:
void waitingForFaces(bool s) { m_waitingForFaces = s;}
bool waitingForHlr() const { return m_waitingForHlr; }
void waitingForHlr(bool s) { m_waitingForHlr = s; }
bool waitingForResult() const;
virtual bool waitingForResult() const;
void progressValueChanged(int v);

View File

@@ -26,32 +26,22 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
//#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
#include <BRepCheck_Wire.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Dir.hxx>
#include <Geom_Plane.hxx>
#include <HLRBRep_Algo.hxx>
#include <HLRAlgo_Projector.hxx>
#include <HLRBRep_HLRToShape.hxx>
#include <ShapeAnalysis.hxx>
#include <ShapeFix_Wire.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Face.hxx>
@@ -60,14 +50,14 @@
#include <TopoDS_Compound.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#endif
#include <chrono>
#include <sstream>
#include <QFile>
#include <QFileInfo>
#include "QtConcurrent/qtconcurrentrun.h"
#include <QtConcurrentRun>
#include <App/Application.h>
#include <App/Document.h>
@@ -163,123 +153,61 @@ DrawViewSection::~DrawViewSection()
short DrawViewSection::mustExecute() const
{
short result = 0;
if (!isRestoring()) {
result = (Scale.isTouched() ||
Direction.isTouched() ||
BaseView.isTouched() ||
SectionNormal.isTouched() ||
SectionOrigin.isTouched() );
if (isRestoring()) {
return TechDraw::DrawView::mustExecute();
}
if (result) {
return result;
if (Scale.isTouched() ||
Direction.isTouched() ||
BaseView.isTouched() ||
SectionNormal.isTouched() ||
SectionOrigin.isTouched() ) {
return 1;
}
return TechDraw::DrawView::mustExecute();
}
void DrawViewSection::onChanged(const App::Property* prop)
{
App::Document* doc = getDocument();
if (!isRestoring()) {
if (prop == &SectionSymbol) {
std::string lblText = "Section " +
std::string(SectionSymbol.getValue()) +
" - " +
std::string(SectionSymbol.getValue());
Label.setValue(lblText);
} else if (prop == &SectionOrigin) {
App::DocumentObject* base = BaseView.getValue();
TechDraw::DrawView* dv = dynamic_cast<TechDraw::DrawView*>(base);
if (dv) {
dv->requestPaint();
}
} else if (prop == &CutSurfaceDisplay) {
if (CutSurfaceDisplay.isValue("PatHatch")) {
makeLineSets();
}
}
if ((prop == &FileHatchPattern) && doc) {
if (!FileHatchPattern.isEmpty()) {
Base::FileInfo fi(FileHatchPattern.getValue());
if (fi.isReadable()) {
replaceSvgIncluded(FileHatchPattern.getValue());
}
}
}
if ((prop == &FileGeomPattern) && doc) {
if (!FileGeomPattern.isEmpty()) {
Base::FileInfo fi(FileGeomPattern.getValue());
if (fi.isReadable()) {
replacePatIncluded(FileGeomPattern.getValue());
}
}
}
if (isRestoring()) {
DrawView::onChanged(prop);
return;
}
if (prop == &FileGeomPattern ||
App::Document* doc = getDocument();
if (prop == &SectionSymbol) {
std::string lblText = "Section " +
std::string(SectionSymbol.getValue()) +
" - " +
std::string(SectionSymbol.getValue());
Label.setValue(lblText);
} else if (prop == &CutSurfaceDisplay) {
if (CutSurfaceDisplay.isValue("PatHatch")) {
makeLineSets();
}
} else if ((prop == &FileHatchPattern) && doc) {
if (!FileHatchPattern.isEmpty()) {
Base::FileInfo fi(FileHatchPattern.getValue());
if (fi.isReadable()) {
replaceSvgIncluded(FileHatchPattern.getValue());
}
}
} else if ((prop == &FileGeomPattern) && doc) {
if (!FileGeomPattern.isEmpty()) {
Base::FileInfo fi(FileGeomPattern.getValue());
if (fi.isReadable()) {
replacePatIncluded(FileGeomPattern.getValue());
}
}
} else if (prop == &FileGeomPattern ||
prop == &NameGeomPattern ) {
makeLineSets();
}
DrawView::onChanged(prop);
}
void DrawViewSection::makeLineSets()
{
// Base::Console().Message("DVS::makeLineSets()\n");
if (!PatIncluded.isEmpty()) {
std::string fileSpec = PatIncluded.getValue();
Base::FileInfo fi(fileSpec);
std::string ext = fi.extension();
if (!fi.isReadable()) {
Base::Console().Message("%s can not read hatch file: %s\n", getNameInDocument(), fileSpec.c_str());
} else {
if ( (ext == "pat") ||
(ext == "PAT") ) {
if ((!fileSpec.empty()) &&
(!NameGeomPattern.isEmpty())) {
std::vector<PATLineSpec> specs =
DrawGeomHatch::getDecodedSpecsFromFile(fileSpec,
NameGeomPattern.getValue());
m_lineSets.clear();
for (auto& hl: specs) {
//hl.dump("hl from section");
LineSet ls;
ls.setPATLineSpec(hl);
m_lineSets.push_back(ls);
}
}
}
}
}
}
//this could probably always use FileHatchPattern as input?
void DrawViewSection::replaceSvgIncluded(std::string newSvgFile)
{
// Base::Console().Message("DVS::replaceSvgHatch(%s)\n", newSvgFile.c_str());
if (SvgIncluded.isEmpty()) {
setupSvgIncluded();
} else {
std::string tempName = SvgIncluded.getExchangeTempFile();
DrawUtil::copyFile(newSvgFile, tempName);
SvgIncluded.setValue(tempName.c_str());
}
}
void DrawViewSection::replacePatIncluded(std::string newPatFile)
{
// Base::Console().Message("DVS::replacePatHatch(%s)\n", newPatFile.c_str());
if (PatIncluded.isEmpty()) {
setupPatIncluded();
} else {
std::string tempName = PatIncluded.getExchangeTempFile();
DrawUtil::copyFile(newPatFile, tempName);
PatIncluded.setValue(tempName.c_str());
}
}
App::DocumentObjectExecReturn *DrawViewSection::execute()
{
if (!keepUpdated()) {
@@ -293,22 +221,23 @@ App::DocumentObjectExecReturn *DrawViewSection::execute()
TechDraw::DrawViewPart* dvp = nullptr;
if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
//this can probably only happen with scripting
return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");
} else {
dvp = static_cast<TechDraw::DrawViewPart*>(base);
}
TopoDS_Shape baseShape;
TopoDS_Shape baseShape = dvp->getSourceShape();
if (FuseBeforeCut.getValue()) {
baseShape = dvp->getSourceShapeFused();
} else {
baseShape = dvp->getSourceShape();
}
if (baseShape.IsNull()) {
return DrawView::execute();
}
m_saveShape = baseShape; //save shape for 2nd pass
// checkXDirection();
bool haveX = checkXDirection();
if (!haveX) {
@@ -322,20 +251,6 @@ App::DocumentObjectExecReturn *DrawViewSection::execute()
sectionExec(baseShape);
addShapes2d();
//second pass if required
if (ScaleType.isValue("Automatic")) {
if (!checkFit()) {
double newScale = autoScale();
Scale.setValue(newScale);
Scale.purgeTouched();
if (geometryObject) {
delete geometryObject;
geometryObject = nullptr;
sectionExec(baseShape);
}
}
}
return DrawView::execute();
}
@@ -344,7 +259,8 @@ void DrawViewSection::sectionExec(TopoDS_Shape& baseShape)
// Base::Console().Message("DVS::sectionExec() - %s baseShape.IsNull: %d\n",
// getNameInDocument(), baseShape.IsNull());
if (waitingForCut()) {
if (waitingForHlr() ||
waitingForCut()) {
return;
}
@@ -352,11 +268,16 @@ void DrawViewSection::sectionExec(TopoDS_Shape& baseShape)
//should be caught before this
return;
}
if (geometryObject) {
delete geometryObject;
geometryObject = nullptr;
}
try {
QObject::connect(&m_cutWatcher, SIGNAL(finished()), this, SLOT(onSectionCutFinished()));
m_cutFuture = QtConcurrent::run(this, &DrawViewSection::makeSectionCut, baseShape);
m_cutWatcher.setFuture(m_cutFuture);
waitingForCut(true);
}
catch (...) {
Base::Console().Message("DVS::sectionExec - failed to make section cut");
@@ -369,7 +290,6 @@ void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape)
// Base::Console().Message("DVS::makeSectionCut() - %s - baseShape.IsNull: %d\n",
// getNameInDocument(), baseShape.IsNull());
waitingForCut(true);
showProgressMessage(getNameInDocument(), "is making section cut");
// cut base shape with tool
@@ -400,6 +320,7 @@ void DrawViewSection::makeSectionCut(TopoDS_Shape &baseShape)
// We need to copy the shape to not modify the BRepstructure
BRepBuilderAPI_Copy BuilderCopy(baseShape);
TopoDS_Shape myShape = BuilderCopy.Shape();
m_saveShape = myShape; //save shape for 2nd pass
// perform cut
BRep_Builder builder;
@@ -502,11 +423,24 @@ void DrawViewSection::postHlrTasks(void)
{
// Base::Console().Message("DVS::postHlrTasks() - %s\n", getNameInDocument());
DrawViewPart::postHlrTasks();
//second pass if required
if (ScaleType.isValue("Automatic")) {
if (!checkFit()) {
double newScale = autoScale();
Scale.setValue(newScale);
Scale.purgeTouched();
sectionExec(m_saveShape);
}
}
overrideKeepUpdated(false);
// build section face geometry
TopoDS_Compound faceIntersections = findSectionPlaneIntersections(m_rawShape);
if (faceIntersections.IsNull()) {
requestPaint();
DrawViewPart::postHlrTasks();
return;
}
@@ -536,32 +470,25 @@ void DrawViewSection::postHlrTasks(void)
BRepBuilderAPI_Transform xformer(fromR3);
xformer.Perform(scaledSection, true);
if (xformer.IsDone()) {
sectionFaces = TopoDS::Compound(xformer.Shape());
// BRepTools::Write(sectionFaces, "DVSXFaces.brep"); //debug
sectionTopoDSFaces = TopoDS::Compound(xformer.Shape());
} else {
Base::Console().Message("DVS::sectionExec - face xform failed\n");
}
sectionFaces = TopoDS::Compound(GeometryObject::invertGeometry(sectionFaces)); //handle Qt -y
sectionTopoDSFaces = TopoDS::Compound(GeometryObject::invertGeometry(sectionTopoDSFaces)); //handle Qt -y
//turn section faces into something we can draw
//turn section faces into TD geometry
tdSectionFaces.clear();
TopExp_Explorer sectionExpl(sectionFaces, TopAbs_FACE);
int iface = 0;
TopExp_Explorer sectionExpl(sectionTopoDSFaces, TopAbs_FACE);
for (; sectionExpl.More(); sectionExpl.Next()) {
iface++;
const TopoDS_Face& face = TopoDS::Face(sectionExpl.Current());
TechDraw::FacePtr sectionFace(std::make_shared<TechDraw::Face>());
TopExp_Explorer expFace(face, TopAbs_WIRE);
int iwire = 0;
for ( ; expFace.More(); expFace.Next()) {
iwire++;
TechDraw::Wire* w = new TechDraw::Wire();
const TopoDS_Wire& wire = TopoDS::Wire(expFace.Current());
int iedge = 0;
TopExp_Explorer expWire(wire, TopAbs_EDGE);
for ( ; expWire.More(); expWire.Next()) {
iedge++;
const TopoDS_Edge& edge = TopoDS::Edge(expWire.Current());
TechDraw::BaseGeomPtr e = BaseGeom::baseFactory(edge);
if (e) {
@@ -573,15 +500,11 @@ void DrawViewSection::postHlrTasks(void)
tdSectionFaces.push_back(sectionFace);
}
App::DocumentObject* base = BaseView.getValue();
if (base != nullptr) {
if (base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(base);
dvp->requestPaint(); //to refresh section line
}
TechDraw::DrawViewPart* dvp = dynamic_cast<TechDraw::DrawViewPart*>(BaseView.getValue());
if (dvp) {
dvp->requestPaint(); //to refresh section line
}
requestPaint();
DrawViewPart::postHlrTasks();
}
//activities that depend on a valid section cut
@@ -590,12 +513,21 @@ void DrawViewSection::postSectionCutTasks()
std::vector<App::DocumentObject*> children = getInList();
for (auto& c: children) {
if (c->getTypeId().isDerivedFrom(DrawViewPart::getClassTypeId())) {
//details or sections need cut shape
//details or sections of this need cut shape
c->recomputeFeature();
}
}
}
bool DrawViewSection::waitingForResult() const
{
if (DrawViewPart::waitingForResult() ||
waitingForCut()) {
return true;
}
return false;
}
gp_Pln DrawViewSection::getSectionPlane() const
{
gp_Ax2 viewAxis = getSectionCS();
@@ -604,14 +536,12 @@ gp_Pln DrawViewSection::getSectionPlane() const
return gp_Pln(viewAxis3);
}
//! tries to find the intersection of the section plane with the shape giving a collection of planar faces
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
{
// Base::Console().Message("DVS::findSectionPlaneIntersections() - %s\n", getNameInDocument());
if(shape.IsNull()){
//a) this shouldn't happen
//b) if it does, we should throw something
// this shouldn't happen
Base::Console().Warning("DrawViewSection::findSectionPlaneInter - %s - input shape is Null\n", getNameInDocument());
return TopoDS_Compound();
}
@@ -622,22 +552,17 @@ TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shap
builder.MakeCompound(result);
TopExp_Explorer expFaces(shape, TopAbs_FACE);
int i;
int dbAdded = 0;
for (i = 1 ; expFaces.More(); expFaces.Next(), i++) {
for ( ; expFaces.More(); expFaces.Next()) {
const TopoDS_Face& face = TopoDS::Face(expFaces.Current());
BRepAdaptor_Surface adapt(face);
if (adapt.GetType() == GeomAbs_Plane){
gp_Pln plnFace = adapt.Plane();
if(plnSection.Contains(plnFace.Location(), Precision::Confusion()) &&
plnFace.Axis().IsParallel(plnSection.Axis(), Precision::Angular())) {
dbAdded++;
builder.Add(result, face);
}
}
}
// BRepTools::Write(result, "DVSIntersect.brep"); //debug
return result;
}
@@ -646,34 +571,32 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawViewSection::sectionLineEnds()
{
std::pair<Base::Vector3d, Base::Vector3d> result;
Base::Vector3d stdZ(0.0, 0.0, 1.0);
double baseRotation = getBaseDVP()->Rotation.getValue(); //Qt degrees
double baseRotation = getBaseDVP()->Rotation.getValue(); //Qt degrees are clockwise
Base::Rotation rotator(stdZ, baseRotation * M_PI / 180.0);
Base::Rotation unrotator(stdZ, - baseRotation * M_PI / 180.0);
auto sNorm = SectionNormal.getValue();
double angle = M_PI / 2.0;
auto axis = getBaseDVP()->Direction.getValue();
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
Base::Vector3d sLineDir = DrawUtil::vecRotate(sNorm, angle, axis, stdOrg);
sLineDir.Normalize();
Base::Vector3d sLineDir2 = - axis.Cross(sNorm);
sLineDir2.Normalize();
Base::Vector3d sLineOnBase = getBaseDVP()->projectPoint(sLineDir2);
sLineOnBase.Normalize();
Base::Vector3d sectionLineDir = - axis.Cross(sNorm);
sectionLineDir.Normalize();
sectionLineDir = getBaseDVP()->projectPoint(sectionLineDir); //convert to base view CS
sectionLineDir.Normalize();
auto sOrigin = SectionOrigin.getValue();
Base::Vector3d adjSectionOrg = sOrigin - getBaseDVP()->getOriginalCentroid();
Base::Vector3d sOrgOnBase = getBaseDVP()->projectPoint(adjSectionOrg);
Base::Vector3d sectionOrg = SectionOrigin.getValue() - getBaseDVP()->getOriginalCentroid();
sectionOrg = getBaseDVP()->projectPoint(sectionOrg); //convert to base view CS
//get the unscaled X and Y ranges of the base view geometry
auto bbx = getBaseDVP()->getBoundingBox();
double xRange = bbx.MaxX - bbx.MinX;
xRange /= getBaseDVP()->getScale();
double yRange = bbx.MaxY - bbx.MinY;
yRange /= getBaseDVP()->getScale();
sOrgOnBase = rotator.multVec(sOrgOnBase);
sLineOnBase = rotator.multVec(sLineOnBase);
result = DrawUtil::boxIntersect2d(sOrgOnBase, sLineOnBase, xRange, yRange); //unscaled
sectionOrg = rotator.multVec(sectionOrg);
sectionLineDir = rotator.multVec(sectionLineDir);
result = DrawUtil::boxIntersect2d(sectionOrg, sectionLineDir, xRange, yRange); //unscaled
result.first = unrotator.multVec(result.first);
result.second = unrotator.multVec(result.second);
@@ -704,26 +627,26 @@ Base::Vector3d DrawViewSection::getXDirection() const
// Base::Console().Message("DVS::getXDirection() - %s\n", Label.getValue());
Base::Vector3d result(1.0, 0.0, 0.0); //default X
App::Property* prop = getPropertyByName("XDirection");
if (prop) { //have an XDirection property
Base::Vector3d propVal = XDirection.getValue();
if (DrawUtil::fpCompare(propVal.Length(), 0.0)) { //but it has no value
std::string sectName = SectionDirection.getValueAsString();
gp_Ax2 cs = getCSFromBase(sectName);
if (prop) {
//we have an XDirection property
if (DrawUtil::fpCompare(XDirection.getValue().Length(), 0.0)) {
//but it has no value, so we make a value
gp_Ax2 cs = getCSFromBase(SectionDirection.getValueAsString());
gp_Dir gXDir = cs.XDirection();
result = Base::Vector3d(gXDir.X(),
gXDir.Y(),
gXDir.Z());
} else {
result = propVal; //normal case. XDirection is set.
//XDirection is good, so we use it
result = XDirection.getValue();
}
} else { //no Property. can this happen?
std::string sectName = SectionDirection.getValueAsString();
gp_Ax2 cs = getCSFromBase(sectName);
gp_Dir gXDir = cs.XDirection();
result = Base::Vector3d(gXDir.X(),
gXDir.Y(),
gXDir.Z());
} else {
//no XDirection property. can this happen?
gp_Ax2 cs = getCSFromBase(SectionDirection.getValueAsString());
gp_Dir gXDir = cs.XDirection();
result = Base::Vector3d(gXDir.X(),
gXDir.Y(),
gXDir.Z());
}
return result;
}
@@ -731,14 +654,13 @@ Base::Vector3d DrawViewSection::getXDirection() const
void DrawViewSection::setCSFromBase(const std::string sectionName)
{
// Base::Console().Message("DVS::setCSFromBase(%s)\n", sectionName.c_str());
gp_Ax2 CS = getCSFromBase(sectionName);
gp_Dir gDir = CS.Direction();
gp_Dir gDir = getCSFromBase(sectionName).Direction();
Base::Vector3d vDir(gDir.X(),
gDir.Y(),
gDir.Z());
Direction.setValue(vDir);
SectionNormal.setValue(vDir);
gp_Dir gxDir = CS.XDirection();
gp_Dir gxDir = getCSFromBase(sectionName).XDirection();
Base::Vector3d vXDir(gxDir.X(),
gxDir.Y(),
gxDir.Z());
@@ -830,15 +752,15 @@ std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
// Base::Console().Message("DVS::getDrawableLines(%d) - lineSets: %d\n", i, m_lineSets.size());
std::vector<LineSet> result;
result = DrawGeomHatch::getTrimmedLinesSection(this,m_lineSets,
getSectionTFace(i),
getSectionTopoDSFace(i),
HatchScale.getValue());
return result;
}
TopoDS_Face DrawViewSection::getSectionTFace(int i)
TopoDS_Face DrawViewSection::getSectionTopoDSFace(int i)
{
TopoDS_Face result;
TopExp_Explorer expl(sectionFaces, TopAbs_FACE);
TopExp_Explorer expl(sectionTopoDSFaces, TopAbs_FACE);
int count = 1;
for (; expl.More(); expl.Next(), count++) {
if (count == i+1) {
@@ -848,15 +770,6 @@ TopoDS_Face DrawViewSection::getSectionTFace(int i)
return result;
}
void DrawViewSection::unsetupObject()
{
TechDraw::DrawViewPart* base = getBaseDVP();
if (base) {
base->touch();
}
DrawViewPart::unsetupObject();
}
TechDraw::DrawViewPart* DrawViewSection::getBaseDVP() const
{
TechDraw::DrawViewPart* baseDVP = nullptr;
@@ -881,43 +794,17 @@ TechDraw::DrawProjGroupItem* DrawViewSection::getBaseDPGI() const
return baseDPGI;
}
void DrawViewSection::getParameters()
// setup / tear down routines
void DrawViewSection::unsetupObject()
{
// Base::Console().Message("DVS::getParameters()\n");
Base::Reference<ParameterGrp>hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
bool fuseFirst = hGrp->GetBool("SectionFuseFirst", false);
FuseBeforeCut.setValue(fuseFirst);
TechDraw::DrawViewPart* base = getBaseDVP();
if (base) {
base->touch();
}
DrawViewPart::unsetupObject();
}
bool DrawViewSection::debugSection() const
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/debug");
bool result = hGrp->GetBool("debugSection",false);
return result;
}
int DrawViewSection::prefCutSurface() const
{
// Base::Console().Message("DVS::prefCutSurface()\n");
Base::Reference<ParameterGrp>hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
int result = hGrp->GetInt("CutSurfaceDisplay", 2); //default to SvgHatch
return result;
}
bool DrawViewSection::showSectionEdges()
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
return (hGrp->GetBool("ShowSectionEdges", true));
}
void DrawViewSection::onDocumentRestored()
{
// Base::Console().Message("DVS::onDocumentRestored()\n");
@@ -954,7 +841,32 @@ void DrawViewSection::setupObject()
DrawViewPart::setupObject();
}
void DrawViewSection::setupSvgIncluded()
//hatch file routines
//create geometric hatch lines
void DrawViewSection::makeLineSets(void)
{
// Base::Console().Message("DVS::makeLineSets()\n");
if (!PatIncluded.isEmpty()) {
std::string fileSpec = PatIncluded.getValue();
Base::FileInfo fi(fileSpec);
std::string ext = fi.extension();
if (!fi.isReadable()) {
Base::Console().Message("%s can not read hatch file: %s\n", getNameInDocument(), fileSpec.c_str());
} else {
if ( (ext == "pat") ||
(ext == "PAT") ) {
if ((!fileSpec.empty()) &&
(!NameGeomPattern.isEmpty())) {
m_lineSets.clear();
m_lineSets = DrawGeomHatch::makeLineSets(fileSpec, NameGeomPattern.getValue());
}
}
}
}
}
void DrawViewSection::setupSvgIncluded(void)
{
// Base::Console().Message("DVS::setupSvgIncluded()\n");
App::Document* doc = getDocument();
@@ -999,6 +911,69 @@ void DrawViewSection::setupPatIncluded()
}
}
//this could probably always use FileHatchPattern as input?
void DrawViewSection::replaceSvgIncluded(std::string newSvgFile)
{
// Base::Console().Message("DVS::replaceSvgHatch(%s)\n", newSvgFile.c_str());
if (SvgIncluded.isEmpty()) {
setupSvgIncluded();
} else {
std::string tempName = SvgIncluded.getExchangeTempFile();
DrawUtil::copyFile(newSvgFile, tempName);
SvgIncluded.setValue(tempName.c_str());
}
}
void DrawViewSection::replacePatIncluded(std::string newPatFile)
{
// Base::Console().Message("DVS::replacePatHatch(%s)\n", newPatFile.c_str());
if (PatIncluded.isEmpty()) {
setupPatIncluded();
} else {
std::string tempName = PatIncluded.getExchangeTempFile();
DrawUtil::copyFile(newPatFile, tempName);
PatIncluded.setValue(tempName.c_str());
}
}
// Parameter fetching routines
void DrawViewSection::getParameters()
{
// Base::Console().Message("DVS::getParameters()\n");
Base::Reference<ParameterGrp>hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
bool fuseFirst = hGrp->GetBool("SectionFuseFirst", false);
FuseBeforeCut.setValue(fuseFirst);
}
bool DrawViewSection::debugSection(void) const
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/debug");
bool result = hGrp->GetBool("debugSection",false);
return result;
}
int DrawViewSection::prefCutSurface(void) const
{
// Base::Console().Message("DVS::prefCutSurface()\n");
Base::Reference<ParameterGrp>hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
int result = hGrp->GetInt("CutSurfaceDisplay", 2); //default to SvgHatch
return result;
}
bool DrawViewSection::showSectionEdges(void)
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
return (hGrp->GetBool("ShowSectionEdges", true));
}
#include <Mod/TechDraw/App/moc_DrawViewSection.cpp>
// Python Drawing feature ---------------------------------------------------------

View File

@@ -104,6 +104,7 @@ public:
virtual void postSectionCutTasks();
void waitingForCut(bool s) { m_waitingForCut = s; }
bool waitingForCut(void) const { return m_waitingForCut; }
bool waitingForResult() const override;
std::vector<TechDraw::FacePtr> getTDFaceGeometry() {return tdSectionFaces;}
@@ -116,10 +117,9 @@ public:
TechDraw::DrawViewPart* getBaseDVP() const;
TechDraw::DrawProjGroupItem* getBaseDPGI() const;
TopoDS_Compound getSectionFaces() { return sectionFaces;}
// std::vector<TopoDS_Wire> getSectionFaceWires(void) { return sectionFaceWires; } //obs?
TopoDS_Face getSectionTFace(int i);
void makeLineSets() ;
TopoDS_Compound getSectionTFaces() { return sectionTopoDSFaces;}
TopoDS_Face getSectionTopoDSFace(int i);
void makeLineSets(void) ;
std::vector<LineSet> getDrawableLines(int i = 0);
std::vector<PATLineSpec> getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern);
@@ -136,8 +136,7 @@ public Q_SLOTS:
void onSectionCutFinished(void);
protected:
TopoDS_Compound sectionFaces; //tSectionFaces
// std::vector<TopoDS_Wire> sectionFaceWires; //obs??? getSectionFaceWires
TopoDS_Compound sectionTopoDSFaces; //needed for hatching
std::vector<LineSet> m_lineSets;
std::vector<TechDraw::FacePtr> tdSectionFaces;

View File

@@ -116,7 +116,8 @@ App::DocumentObjectExecReturn *DrawViewSpreadsheet::execute()
return new App::DocumentObjectExecReturn("Empty cell value");
Symbol.setValue(getSheetImage());
overrideKeepUpdated(false);
return TechDraw::DrawView::execute();
}

View File

@@ -120,9 +120,10 @@ App::DocumentObjectExecReturn *DrawWeldSymbol::execute()
{
// Base::Console().Message("DWS::execute()\n");
if (!keepUpdated()) {
return App::DocumentObject::StdReturn;
return DrawView::execute();
}
overrideKeepUpdated(false);
return DrawView::execute();
}

View File

@@ -19,7 +19,7 @@
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
//this file originally part of TechDraw workbench
//this file originally part of Drawing workbench
//migrated to TechDraw workbench 2022-01-26 by Wandererfan

View File

@@ -178,10 +178,10 @@ void GeometryObject::projectShape(const TopoDS_Shape& inShape,
catch (const Standard_Failure& e) {
Base::Console().Error("GO::projectShape - OCC error - %s - while projecting shape\n",
e.GetMessageString());
throw Base::RuntimeError("GeometryObject::hlrExecute - OCC error");
throw Base::RuntimeError("GeometryObject::projectShape - OCC error");
}
catch (...) {
throw Base::RuntimeError("GeometryObject::hlrExecute - unknown error");
throw Base::RuntimeError("GeometryObject::projectShape - unknown error");
}
try {
@@ -249,13 +249,18 @@ void GeometryObject::projectShape(const TopoDS_Shape& inShape,
}
}
catch (const Standard_Failure& e) {
throw Base::RuntimeError("GeometryObject::hlrExecute - OCC error occurred while extracting edges");
throw Base::RuntimeError("GeometryObject::projectShape - OCC error occurred while extracting edges");
}
catch (...) {
throw Base::RuntimeError("GeometryObject::hlrExecute - unknown error occurred while extracting edges");
throw Base::RuntimeError("GeometryObject::projectShape - unknown error occurred while extracting edges");
}
//convert the hlr output into TD Geometry
makeTDGeometry();
}
//convert the hlr output into TD Geometry
void GeometryObject::makeTDGeometry()
{
extractGeometry(TechDraw::ecHARD, //always show the hard&outline visible lines
true);
extractGeometry(TechDraw::ecOUTLINE,
@@ -340,8 +345,6 @@ void GeometryObject::projectShapeWithPolygonAlgo(const TopoDS_Shape& input,
inCopy = BuilderCopy.Shape();
}
auto start = chrono::high_resolution_clock::now();
Handle(HLRBRep_PolyAlgo) brep_hlrPoly;
try {
@@ -369,11 +372,10 @@ void GeometryObject::projectShapeWithPolygonAlgo(const TopoDS_Shape& input,
catch (const Standard_Failure& e) {
Base::Console().Error("GO::projectShapeWithPolygonAlgo - OCC error - %s - while projecting shape\n",
e.GetMessageString());
throw Base::RuntimeError("GeometryObject::projectShapeWithPolygonAlgo - OCC error");
}
catch (...) {
Base::Console().Error("GO::projectShapeWithPolygonAlgo - unknown error while projecting shape\n");
// throw Base::RuntimeError("GeometryObject::projectShapeWithPolygonAlgo - error occurred while projecting shape");
// Standard_Failure::Raise("GeometryObject::projectShapeWithPolygonAlgo - error occurred while projecting shape");
throw Base::RuntimeError("GeometryObject::projectShapeWithPolygonAlgo - unknown error");
}
try {
@@ -417,16 +419,13 @@ void GeometryObject::projectShapeWithPolygonAlgo(const TopoDS_Shape& input,
catch (const Standard_Failure& e) {
Base::Console().Error("GO::projectShapeWithPolygonAlgo - OCC error - %s - while extracting edges\n",
e.GetMessageString());
throw Base::RuntimeError("GeometryObject::projectShapeWithPolygonAlgo - OCC error occurred while extracting edges");
}
catch (...) {
Base::Console().Error("GO::projectShapeWithPolygonAlgo - - error occurred while extracting edges\n");
// throw Base::RuntimeError("GeometryObject::projectShapeWithPolygonAlgo - error occurred while extracting edges");
// Standard_Failure::Raise("GeometryObject::projectShapeWithPolygonAlgo - error occurred while extracting edges");
throw Base::RuntimeError("GeometryObject::projectShapeWithPolygonAlgo - unknown error occurred while extracting edges");
}
auto end = chrono::high_resolution_clock::now();
auto diff = end - start;
double diffOut = chrono::duration <double, milli>(diff).count();
Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_PolyAlgo & co\n", m_parentName.c_str(), diffOut);
makeTDGeometry();
}
TopoDS_Shape GeometryObject::projectFace(const TopoDS_Shape &face,

View File

@@ -122,6 +122,7 @@ public:
TopoDS_Shape projectFace(const TopoDS_Shape &face,
const gp_Ax2 &CS);
void makeTDGeometry();
void extractGeometry(edgeClass category, bool visible);
void addFaceGeom(FacePtr f);
void clearFaceGeom();

View File

@@ -153,7 +153,9 @@ App::DocumentObjectExecReturn *LandmarkDimension::execute()
// dvp->resetReferenceVerts();
dvp->addReferencesToGeom();
dvp->requestPaint();
dvp->requestPaint();
overrideKeepUpdated(false);
return dvdResult;
}

View File

@@ -340,10 +340,9 @@ QGIViewClip* QGIView::getClipGroup()
return result;
}
void QGIView::updateView(bool update)
void QGIView::updateView(bool forceUpdate)
{
// Base::Console().Message("QGIV::updateView() - %s\n",getViewObject()->getNameInDocument());
(void) update;
//allow/prevent dragging
if (getViewObject()->isLocked()) {
@@ -352,6 +351,11 @@ void QGIView::updateView(bool update)
setFlag(QGraphicsItem::ItemIsMovable, true);
}
if (getViewObject() && forceUpdate) {
setPosition(Rez::guiX(getViewObject()->X.getValue()),
Rez::guiX(getViewObject()->Y.getValue()));
}
double appRotation = getViewObject()->Rotation.getValue();
double guiRotation = rotation();
if (!TechDraw::DrawUtil::fpCompare(appRotation,guiRotation)) {

View File

@@ -67,25 +67,26 @@ void QGIViewSection::draw()
void QGIViewSection::drawSectionFace()
{
auto section( dynamic_cast<TechDraw::DrawViewSection *>(getViewObject()) );
if (!section)
if (!section) {
return;
}
if (!section->hasGeometry())
if (!section->hasGeometry()) {
return;
}
Gui::ViewProvider* gvp = QGIView::getViewProvider(section);
ViewProviderViewSection* sectionVp = dynamic_cast<ViewProviderViewSection*>(gvp);
if (!sectionVp || !sectionVp->ShowCutSurface.getValue())
return;
float lineWidth = sectionVp->LineWidth.getValue();
auto sectionFaces( section->getTDFaceGeometry() );
if (sectionFaces.empty()) {
Base::Console().
Log("INFO - QGIViewSection::drawSectionFace - No sectionFaces available. Check Section plane.\n");
return;
}
float lineWidth = sectionVp->LineWidth.getValue();
std::vector<TechDraw::FacePtr>::iterator fit = sectionFaces.begin();
int i = 0;
for(; fit != sectionFaces.end(); fit++, i++) {

View File

@@ -264,7 +264,7 @@ void TaskProjGroup::scaleTypeChanged(int index)
// Automatic Scale Type
//block recompute
multiView->ScaleType.setValue("Automatic");
double autoScale = multiView->calculateAutomaticScale();
double autoScale = multiView->autoScale();
multiView->Scale.setValue(autoScale);
//unblock recompute

View File

@@ -350,7 +350,6 @@ void ViewProviderPage::removeMDIView(void)
MDIViewPage* ViewProviderPage::getMDIViewPage() const
{
if (m_mdiView.isNull()) {
Base::Console().Log("VPP::getMDIViewPage has no m_mdiView!\n");
return nullptr;
}
return m_mdiView;

View File

@@ -70,20 +70,6 @@ ViewProviderRichAnno::~ViewProviderRichAnno()
{
}
bool ViewProviderRichAnno::setEdit(int ModNum)
{
// Base::Console().Message("VPRA::setEdit(%d)\n",ModNum);
if (ModNum != ViewProvider::Default ) {
return ViewProviderDrawingView::setEdit(ModNum);
}
if (Gui::Control().activeDialog()) { //TaskPanel already open!
return false;
}
Gui::Selection().clearSelection();
Gui::Control().showDialog(new TaskDlgRichAnno(this));
return true;
}
bool ViewProviderRichAnno::doubleClicked()
{
// Base::Console().Message("VPRA::doubleClicked()\n");

View File

@@ -55,7 +55,6 @@ public:
bool useNewSelectionModel() const override {return false;}
void updateData(const App::Property*) override;
void onChanged(const App::Property* p) override;
bool setEdit(int ModNum) override;
bool doubleClicked() override;
bool canDelete(App::DocumentObject* obj) const override;