From 8459cdad5a104e99beb716c87ee880e901bec110 Mon Sep 17 00:00:00 2001 From: WandererFan Date: Wed, 28 Sep 2016 20:18:44 -0400 Subject: [PATCH] Performance improvements Ph1 --- src/Mod/TechDraw/App/DrawPage.cpp | 8 +- src/Mod/TechDraw/App/DrawProjGroup.cpp | 2 +- src/Mod/TechDraw/App/DrawProjGroupItem.cpp | 2 +- src/Mod/TechDraw/App/DrawView.cpp | 7 +- src/Mod/TechDraw/App/DrawViewClip.cpp | 21 +-- src/Mod/TechDraw/App/DrawViewCollection.cpp | 3 +- src/Mod/TechDraw/App/DrawViewDimension.cpp | 34 +--- src/Mod/TechDraw/App/DrawViewPart.cpp | 186 ++++++++++++-------- src/Mod/TechDraw/App/DrawViewPart.h | 1 + src/Mod/TechDraw/App/DrawViewSection.cpp | 8 +- src/Mod/TechDraw/App/GeometryObject.cpp | 12 +- 11 files changed, 150 insertions(+), 134 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawPage.cpp b/src/Mod/TechDraw/App/DrawPage.cpp index a9010ab73..217cd252b 100644 --- a/src/Mod/TechDraw/App/DrawPage.cpp +++ b/src/Mod/TechDraw/App/DrawPage.cpp @@ -153,6 +153,7 @@ short DrawPage::mustExecute() const return 1; // Check if within this Page, any Views have been touched + // Why does Page have to execute if a View changes? bool ViewsTouched = false; const std::vector &vals = Views.getValues(); for(std::vector::const_iterator it = vals.begin(); it < vals.end(); ++it) { @@ -275,7 +276,6 @@ int DrawPage::removeView(App::DocumentObject *docObj) } } Views.setValues(newViews); - Views.touch(); return Views.getSize(); } @@ -287,14 +287,16 @@ void DrawPage::onDocumentRestored() //first, make sure all the Parts have been executed so GeometryObjects exist for(; it != featViews.end(); ++it) { TechDraw::DrawViewPart *part = dynamic_cast(*it); - if (part != NULL) { + if (part != nullptr && + !part->hasGeometry()) { part->execute(); } } //second, make sure all the Dimensions have been executed so Measurements have References for(it = featViews.begin(); it != featViews.end(); ++it) { TechDraw::DrawViewDimension *dim = dynamic_cast(*it); - if (dim != NULL) { + if (dim != nullptr && + !dim->has2DReferences()) { dim->execute(); } } diff --git a/src/Mod/TechDraw/App/DrawProjGroup.cpp b/src/Mod/TechDraw/App/DrawProjGroup.cpp index 300ec9cb8..22b75430e 100644 --- a/src/Mod/TechDraw/App/DrawProjGroup.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroup.cpp @@ -666,7 +666,7 @@ App::Enumeration DrawProjGroup::usedProjectionType(void) void DrawProjGroup::onDocumentRestored() { - execute(); + DrawViewCollection::onDocumentRestored(); } PyObject *DrawProjGroup::getPyObject(void) diff --git a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp index 08e0c75ec..df407521c 100644 --- a/src/Mod/TechDraw/App/DrawProjGroupItem.cpp +++ b/src/Mod/TechDraw/App/DrawProjGroupItem.cpp @@ -89,7 +89,7 @@ DrawProjGroupItem::~DrawProjGroupItem() void DrawProjGroupItem::onDocumentRestored() { setAutoPos(false); //if restoring from file, use X,Y from file, not auto! - execute(); + DrawProjGroupItem::execute(); } diff --git a/src/Mod/TechDraw/App/DrawView.cpp b/src/Mod/TechDraw/App/DrawView.cpp index 98265078a..f8ba3bbee 100644 --- a/src/Mod/TechDraw/App/DrawView.cpp +++ b/src/Mod/TechDraw/App/DrawView.cpp @@ -94,7 +94,7 @@ App::DocumentObjectExecReturn *DrawView::execute(void) } } } - return App::DocumentObject::execute(); + return App::DocumentObject::StdReturn; //DO::execute returns 0 } void DrawView::onChanged(const App::Property* prop) @@ -133,9 +133,8 @@ short DrawView::mustExecute() const } if (result) { return result; - } else { - return App::DocumentObject::mustExecute(); } + return App::DocumentObject::mustExecute(); return App::DocumentObject::mustExecute(); } ////you must override this in derived class @@ -148,7 +147,7 @@ QRectF DrawView::getRect() const void DrawView::onDocumentRestored() { // Rebuild the view - execute(); + DrawView::execute(); } DrawPage* DrawView::findParentPage() const diff --git a/src/Mod/TechDraw/App/DrawViewClip.cpp b/src/Mod/TechDraw/App/DrawViewClip.cpp index 5478be043..50c0b14ee 100644 --- a/src/Mod/TechDraw/App/DrawViewClip.cpp +++ b/src/Mod/TechDraw/App/DrawViewClip.cpp @@ -74,14 +74,6 @@ DrawViewClip::~DrawViewClip() void DrawViewClip::onChanged(const App::Property* prop) { - if (prop == &Height || - prop == &Width || - prop == &Views) { - if (!isRestoring()) { - DrawViewClip::execute(); - } - } - DrawView::onChanged(prop); } @@ -126,11 +118,16 @@ App::DocumentObjectExecReturn *DrawViewClip::execute(void) short DrawViewClip::mustExecute() const { - if (Views.isTouched()) { - return 1; - } else { - return TechDraw::DrawView::mustExecute(); + short result = 0; + if (!isRestoring()) { + result = ( Height.isTouched() || + Width.isTouched() || + Views.isTouched()); } + if (result) { + return result; + } + return TechDraw::DrawView::mustExecute(); } std::vector DrawViewClip::getChildViewNames() diff --git a/src/Mod/TechDraw/App/DrawViewCollection.cpp b/src/Mod/TechDraw/App/DrawViewCollection.cpp index 4c0de80e3..1682925c3 100644 --- a/src/Mod/TechDraw/App/DrawViewCollection.cpp +++ b/src/Mod/TechDraw/App/DrawViewCollection.cpp @@ -147,8 +147,7 @@ int DrawViewCollection::countChildren() void DrawViewCollection::onDocumentRestored() { - // Rebuild the view - execute(); + DrawView::execute(); } void DrawViewCollection::onChanged(const App::Property* prop) diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index 5e311fade..5d56363a3 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -127,30 +127,11 @@ DrawViewDimension::~DrawViewDimension() void DrawViewDimension::onChanged(const App::Property* prop) { if (!isRestoring()) { - if (prop == &References2D || - prop == &Font || - prop == &Fontsize || - prop == &FormatSpec || - //prop == &CentreLines || - prop == &LineWidth) { - try { - App::DocumentObjectExecReturn *ret = recompute(); - delete ret; - } - catch (...) { - } - } if (prop == &MeasureType) { if (MeasureType.isValue("True") && !measurement->has3DReferences()) { Base::Console().Warning("Dimension %s missing Reference to 3D model. Must be Projected.\n", getNameInDocument()); MeasureType.setValue("Projected"); } - try { - App::DocumentObjectExecReturn *ret = recompute(); - delete ret; - } - catch (...) { - } } if (prop == &References3D) { //have to rebuild the Measurement object clear3DMeasurements(); @@ -176,14 +157,15 @@ void DrawViewDimension::onDocumentRestored() short DrawViewDimension::mustExecute() const { bool result = 0; - if (References2D.isTouched() || - Type.isTouched() || - MeasureType.isTouched()) { - result = 1; - } else { - result = 0; + if (!isRestoring()) { + result = (References2D.isTouched() || + Type.isTouched() || + MeasureType.isTouched()); } - return result; + if (result) { + return result; + } + return DrawView::mustExecute(); } App::DocumentObjectExecReturn *DrawViewDimension::execute(void) diff --git a/src/Mod/TechDraw/App/DrawViewPart.cpp b/src/Mod/TechDraw/App/DrawViewPart.cpp index b67caff04..c6a36afdd 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.cpp +++ b/src/Mod/TechDraw/App/DrawViewPart.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -63,11 +64,14 @@ #endif #include +#include +#include #include #include #include #include +#include #include #include "DrawUtil.h" @@ -125,6 +129,9 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0) ADD_PROPERTY_TYPE(SymbolSection,("A") ,lgroup,App::Prop_None,"Section identifier"); geometryObject = new TechDrawGeometry::GeometryObject(); + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/RunControl"); + m_interAlgo = hGrp->GetInt("InterAlgo", 2l); } DrawViewPart::~DrawViewPart() @@ -149,13 +156,10 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) return new App::DocumentObjectExecReturn("FVP - Linked shape object is empty"); } + (void) DrawView::execute(); //make sure Scale is up to date + geometryObject->setTolerance(Tolerance.getValue()); - double s = Scale.getValue(); - if (!s) { //might be problem, might be mid property change - Base::Console().Log("INFO - DVP::execute - Scale: %.3f\n",s); - return DrawView::execute(); - } - geometryObject->setScale(s); + geometryObject->setScale(Scale.getValue()); //TODO: remove these try/catch block when code is stable gp_Pnt inputCenter; @@ -203,17 +207,7 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void) } #endif //#if MOD_TECHDRAW_HANDLE_FACES - //TODO: not sure about this - // There is a guaranteed change so check any references linked to this and touch - // We need to update all views pointing at this (ProjectionGroup, ClipGroup, Section, etc) -// std::vector parent = getInList(); -// for (std::vector::iterator it = parent.begin(); it != parent.end(); ++it) { -// if ((*it)->getTypeId().isDerivedFrom(DrawView::getClassTypeId())) { -// TechDraw::DrawView *view = static_cast(*it); -// view->touch(); -// } -// } - return DrawView::execute(); + return App::DocumentObject::StdReturn; } short DrawViewPart::mustExecute() const @@ -223,13 +217,8 @@ short DrawViewPart::mustExecute() const result = (Direction.isTouched() || XAxisDirection.isTouched() || Source.isTouched() || - Scale.isTouched() || - ScaleType.isTouched() || - Tolerance.isTouched() || - ShowHiddenLines.isTouched() || - ShowSmoothLines.isTouched() || - ShowSeamLines.isTouched() ); - } + Scale.isTouched() ); + } if (result) { return result; @@ -239,28 +228,9 @@ short DrawViewPart::mustExecute() const void DrawViewPart::onChanged(const App::Property* prop) { - if (!isRestoring()) { - if (prop == &SymbolSection && getSectionRef()) { - getSectionRef()->touch(); - } - if (prop == &Direction || - prop == &XAxisDirection || - prop == &Source || - prop == &Scale || - prop == &ScaleType || - prop == &ShowHiddenLines || - prop == &ShowSmoothLines || - prop == &ShowSeamLines) - try { - App::DocumentObjectExecReturn *ret = recompute(); - delete ret; - } - catch (...) { - } - } DrawView::onChanged(prop); -//TODO: when scale changes, any Dimensions for this View sb recalculated. (might happen anyway if document is recomputed?) +//TODO: when scale changes, any Dimensions for this View sb recalculated. DVD should pick this up subject to topological naming issues. } void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) @@ -275,29 +245,26 @@ void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter) inputCenter, Direction.getValue(), validXDir); - //TODO: why not be all line type in 1 call to extract geometry geometryObject->extractGeometry(TechDrawGeometry::ecHARD, true); geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, true); - //if (ShowSmoothLines.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecSMOOTH, - true); - //} - //if (ShowSeamLines.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecSEAM, - true); - //} - //if (ShowIsoLines.getValue()) { - // geometryObject->extractGeometry(TechDrawGeometry::ecUVISO, - // true); - //} - //if (ShowHiddenLines.getValue()) { - geometryObject->extractGeometry(TechDrawGeometry::ecHARD, - false); - //geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, //hidden outline,smooth,seam?? - // true); - //} + geometryObject->extractGeometry(TechDrawGeometry::ecSMOOTH, + true); + geometryObject->extractGeometry(TechDrawGeometry::ecSEAM, + true); +// geometryObject->extractGeometry(TechDrawGeometry::ecUVISO, +// true); + geometryObject->extractGeometry(TechDrawGeometry::ecHARD, + false); +// geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE, +// false); +// geometryObject->extractGeometry(TechDrawGeometry::ecSMOOTH, +// false); +// geometryObject->extractGeometry(TechDrawGeometry::ecSEAM, +// false); +// geometryObject->extractGeometry(TechDrawGeometry::ecUVISO, +// false); bbox = geometryObject->calcBoundingBox(); } @@ -309,7 +276,7 @@ void DrawViewPart::extractFaces() std::vector::const_iterator itEdge = goEdges.begin(); std::vector origEdges; for (;itEdge != goEdges.end(); itEdge++) { - if ((*itEdge)->visible) { //don't make invisible faces! + if ((*itEdge)->visible) { //don't make invisible faces! //TODO: only use Seam/Smooth if checked origEdges.push_back((*itEdge)->occEdge); } } @@ -428,24 +395,89 @@ double DrawViewPart::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) const return minDist; } +//this routine is the big time consumer. gets called many times (and is slow?)) bool DrawViewPart::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, bool allowEnds) { bool result = false; - double dist = simpleMinDist(v,e); - if (dist < 0.0) { - Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist); - result = false; - } else if (dist < Precision::Confusion()) { - result = true; - } - if (result) { - TopoDS_Vertex v1 = TopExp::FirstVertex(e); - TopoDS_Vertex v2 = TopExp::LastVertex(e); - if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { - if (!allowEnds) { - result = false; + bool outOfBox = false; + +//0) using parameterOnEdge + if (m_interAlgo == 0) { + try { //v. fast,but misses some edge/faces?? faster w/o bndbox check + Standard_Real par = BRep_Tool::Parameter(v, e); //if this doesn't throw except then v is on e + result = true; + BRepAdaptor_Curve adapt(e); + double first = BRepLProp_CurveTool::FirstParameter(adapt); + double last = BRepLProp_CurveTool::LastParameter(adapt); + if ((fabs(par - first) < Precision::Confusion()) || + (fabs(par - last) < Precision::Confusion())) { + if (!allowEnds) { + result = false; + } } } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); //"no parameter on Edge" + } + } else { + //eliminate obvious cases + Bnd_Box sBox; + BRepBndLib::Add(e, sBox); + sBox.SetGap(0.1); + if (sBox.IsVoid()) { + Base::Console().Message("DVP::isOnEdge - Bnd_Box is void for %s\n",getNameInDocument()); + } else { + gp_Pnt pt = BRep_Tool::Pnt(v); + if (sBox.IsOut(pt)) { + outOfBox = true; + } + } + if (!outOfBox) { + if (m_interAlgo == 1) { + //1) using projPointOnCurve. roughly similar to dist to shape w/ bndbox. hangs(?) w/o bndbox + try { + gp_Pnt pt = BRep_Tool::Pnt(v); + BRepAdaptor_Curve adapt(e); + Handle_Geom_Curve c = adapt.Curve().Curve(); + GeomAPI_ProjectPointOnCurve proj(pt,c); + int n = proj.NbPoints(); + if (n > 0) { + if (proj.LowerDistance() < Precision::Confusion()) { + result = true; + } + double par = proj.LowerDistanceParameter(); + double first = BRepLProp_CurveTool::FirstParameter(adapt); + double last = BRepLProp_CurveTool::LastParameter(adapt); + if ((fabs(par - first) < Precision::Confusion()) || + (fabs(par - last) < Precision::Confusion())) { + if (!allowEnds) { + result = false; + } + } + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); //no perp projection + } + } else if (m_interAlgo == 2) { //this is the original and still best algorithm + double dist = simpleMinDist(v,e); + if (dist < 0.0) { + Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist); + result = false; + } else if (dist < Precision::Confusion()) { + result = true; + } + if (result) { + TopoDS_Vertex v1 = TopExp::FirstVertex(e); + TopoDS_Vertex v2 = TopExp::LastVertex(e); + if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) { + if (!allowEnds) { + result = false; + } + } + } + } //method 2 + } //!outofbox } return result; } diff --git a/src/Mod/TechDraw/App/DrawViewPart.h b/src/Mod/TechDraw/App/DrawViewPart.h index 8a95028a7..2b650fab7 100644 --- a/src/Mod/TechDraw/App/DrawViewPart.h +++ b/src/Mod/TechDraw/App/DrawViewPart.h @@ -141,6 +141,7 @@ protected: Base::Vector3d vDir; //paperspace Y Base::Vector3d wDir; //paperspace Z Base::Vector3d shapeCentroid; + int m_interAlgo; private: static App::PropertyFloatConstraint::Constraints floatRange; diff --git a/src/Mod/TechDraw/App/DrawViewSection.cpp b/src/Mod/TechDraw/App/DrawViewSection.cpp index 4302721ae..331e01b74 100644 --- a/src/Mod/TechDraw/App/DrawViewSection.cpp +++ b/src/Mod/TechDraw/App/DrawViewSection.cpp @@ -96,7 +96,6 @@ DrawViewSection::DrawViewSection() ADD_PROPERTY_TYPE(ShowCutSurface ,(true),fgroup,App::Prop_None,"Show the cut surface"); ADD_PROPERTY_TYPE(CutSurfaceColor,(fcColor),fgroup,App::Prop_None,"The color to shade the cut surface"); - geometryObject = new TechDrawGeometry::GeometryObject(); } @@ -109,7 +108,6 @@ short DrawViewSection::mustExecute() const short result = 0; if (!isRestoring()) { result = (Scale.isTouched() || - ScaleType.isTouched() || Direction.isTouched() || XAxisDirection.isTouched() || BaseView.isTouched() || @@ -119,7 +117,7 @@ short DrawViewSection::mustExecute() const if (result) { return result; } - return TechDraw::DrawViewPart::mustExecute(); + return TechDraw::DrawView::mustExecute(); } App::DocumentObjectExecReturn *DrawViewSection::execute(void) @@ -142,6 +140,8 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) if (partTopo.getShape().IsNull()) return new App::DocumentObjectExecReturn("Linked shape object is empty"); + (void) DrawView::execute(); //make sure Scale is up to date + gp_Pln pln = getSectionPlane(); // Get the Axis Directions for the Plane to transform UV components again gp_XYZ xAxis = pln.XAxis().Direction().XYZ(); @@ -254,7 +254,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void) return new App::DocumentObjectExecReturn(e2->GetMessageString()); } - return DrawView::execute(); + return App::DocumentObject::StdReturn; } gp_Pln DrawViewSection::getSectionPlane() const diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index fcf0e7ab5..f7bde25a8 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -56,6 +56,7 @@ #endif // #ifndef _PreComp_ #include +#include #include #include @@ -69,6 +70,7 @@ //#include using namespace TechDrawGeometry; +using namespace std; struct EdgePoints { gp_Pnt v1, v2; @@ -131,13 +133,11 @@ void GeometryObject::projectShape(const TopoDS_Shape& input, // Clear previous Geometry clear(); - //next 2 lines might make HLR quicker, but not dramatically - BRepMesh_IncrementalMesh(input, Tolerance); - BRepLib::BuildCurves3d(input); + auto start = chrono::high_resolution_clock::now(); Handle_HLRBRep_Algo brep_hlr = NULL; try { - brep_hlr = new HLRBRep_Algo(); //leak? when does this get freed? handle/smart pointer? + brep_hlr = new HLRBRep_Algo(); brep_hlr->Add(input); // Project the shape into view space with the object's centroid @@ -154,6 +154,10 @@ void GeometryObject::projectShape(const TopoDS_Shape& input, catch (...) { Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape"); } + auto end = chrono::high_resolution_clock::now(); + auto diff = end - start; + double diffOut = chrono::duration (diff).count(); + Base::Console().Log("TIMING - GO spent: %.3f millisecs in HLRBRep_Algo & co\n",diffOut); try { HLRBRep_HLRToShape hlrToShape(brep_hlr);