From e1e9c7e7bde4216640cbbe6bb7463d86ca2e9fb9 Mon Sep 17 00:00:00 2001 From: wandererfan Date: Sun, 8 Dec 2019 20:34:47 -0500 Subject: [PATCH] [TD]add ability to filter obvious geometry errors - also add checks for geometry errors --- src/Mod/TechDraw/App/DrawUtil.cpp | 70 ++++- src/Mod/TechDraw/App/DrawUtil.h | 1 + src/Mod/TechDraw/App/Geometry.cpp | 325 ++++++++++-------------- src/Mod/TechDraw/App/Geometry.h | 1 + src/Mod/TechDraw/App/GeometryObject.cpp | 14 +- src/Mod/TechDraw/Gui/QGIViewPart.cpp | 4 + 6 files changed, 218 insertions(+), 197 deletions(-) diff --git a/src/Mod/TechDraw/App/DrawUtil.cpp b/src/Mod/TechDraw/App/DrawUtil.cpp index 0bc12427a5..69460e9a2f 100644 --- a/src/Mod/TechDraw/App/DrawUtil.cpp +++ b/src/Mod/TechDraw/App/DrawUtil.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -641,6 +643,69 @@ PyObject* DrawUtil::colorToPyTuple(App::Color color) return pTuple; } +//check for crazy edge. This is probably a geometry error of some sort. +bool DrawUtil::isCrazy(TopoDS_Edge e) +{ + bool result = false; + double ratio = 1.0; + + if (e.IsNull()) { + result = true; + return result; + } + + Base::Reference hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")-> + GetGroup("Preferences")->GetGroup("Mod/TechDraw/debug"); + bool crazyOK = hGrp->GetBool("allowCrazyEdge", true); + if (crazyOK) { + return false; + } + + BRepAdaptor_Curve adapt(e); + + double edgeLength = GCPnts_AbscissaPoint::Length(adapt, Precision::Confusion()); + if (edgeLength < 0.00001) { //edge is scaled. this is 0.00001 mm on paper + Base::Console().Log("DU::isCrazy - edge crazy short: %.7f\n", edgeLength); + result = true; + return result; + } + if (edgeLength > 9999.9) { //edge is scaled. this is 10 m on paper. can't be right? + Base::Console().Log("DU::isCrazy - edge crazy long: %.3f\n", edgeLength); + result = true; + return result; + } + + double start = BRepLProp_CurveTool::FirstParameter(adapt); + double end = BRepLProp_CurveTool::LastParameter(adapt); + BRepLProp_CLProps propStart(adapt,start,0,Precision::Confusion()); + const gp_Pnt& vStart = propStart.Value(); + BRepLProp_CLProps propEnd(adapt,end,0,Precision::Confusion()); + const gp_Pnt& vEnd = propEnd.Value(); + double distance = vStart.Distance(vEnd); + if (adapt.GetType() == GeomAbs_BSplineCurve) { + if (distance > 0.001) { // not a closed loop + ratio = edgeLength / distance; + if (ratio > 9999.9) { // 10,000x + result = true; //this is crazy edge + } + } + } else if (adapt.GetType() == GeomAbs_Ellipse) { + gp_Elips ellp = adapt.Ellipse(); + double major = ellp.MajorRadius(); + double minor = ellp.MinorRadius(); + if (minor < 0.001) { //too narrow + Base::Console().Log("DU::isCrazy - ellipse is crazy narrow: %.7f\n", minor); + result = true; + } else if (major > 9999.9) { //too big + Base::Console().Log("DU::isCrazy - ellipse is crazy wide: %.3f\n", major); + result = true; + } + } + +// Base::Console().Message("DU::isCrazy - returns: %d ratio: %.3f\n", result, ratio); + return result; +} + // Supplementary mathematical functions // ==================================== @@ -1048,7 +1113,6 @@ void DrawUtil::dumpEdges(const char* text, const TopoDS_Shape& s) } } - void DrawUtil::dump1Vertex(const char* text, const TopoDS_Vertex& v) { Base::Console().Message("DUMP - dump1Vertex - %s\n",text); @@ -1069,7 +1133,11 @@ void DrawUtil::dumpEdge(const char* label, int i, TopoDS_Edge e) // vStart.X(),vStart.Y(),vStart.Z(),start,vEnd.X(),vEnd.Y(),vEnd.Z(),end); Base::Console().Message("%s edge:%d start:(%.3f,%.3f,%.3f) end:(%.2f,%.3f,%.3f) Orient: %d\n",label,i, vStart.X(),vStart.Y(),vStart.Z(),vEnd.X(),vEnd.Y(),vEnd.Z(), e.Orientation()); + double edgeLength = GCPnts_AbscissaPoint::Length(adapt, Precision::Confusion()); + Base::Console().Message(">>>>>>> length: %.3f distance: %.3f ration: %.3f type: %d\n", edgeLength, + vStart.Distance(vEnd), edgeLength / vStart.Distance(vEnd), adapt.GetType()); } + const char* DrawUtil::printBool(bool b) { return (b ? "True" : "False"); diff --git a/src/Mod/TechDraw/App/DrawUtil.h b/src/Mod/TechDraw/App/DrawUtil.h index ed03583812..1c9901de61 100644 --- a/src/Mod/TechDraw/App/DrawUtil.h +++ b/src/Mod/TechDraw/App/DrawUtil.h @@ -114,6 +114,7 @@ class TechDrawExport DrawUtil { static std::vector tokenize(std::string csvLine, std::string delimiter = ",$$$,"); static App::Color pyTupleToColor(PyObject* pColor); static PyObject* colorToPyTuple(App::Color color); + static bool isCrazy(TopoDS_Edge e); // Supplementary mathematical functions static int sgn(double x); diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index 463654d2e5..658696ce56 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -229,11 +229,6 @@ void BaseGeom::Restore(Base::XMLReader &reader) m_sourceIndex = reader.getAttributeAsInteger("value"); reader.readElement("CosmeticTag"); cosmeticTag = reader.getAttribute("value"); -// reader.readElement("Tag"); -// std::string temp = reader.getAttribute("value"); -// boost::uuids::string_generator gen; -// boost::uuids::uuid u1 = gen(temp); -// tag = u1; } std::vector BaseGeom::findEndPoints() @@ -393,6 +388,14 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) if (edge.IsNull()) { Base::Console().Message("BG::baseFactory - input edge is NULL \n"); } + //weed out rubbish edges before making geometry + if (!validateEdge(edge)) { + return result; + } + + Generic *primitive = new Generic(edge); + result = primitive; + BRepAdaptor_Curve adapt(edge); switch(adapt.GetType()) { case GeomAbs_Circle: { @@ -401,6 +404,9 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) gp_Pnt s = adapt.Value(f); gp_Pnt e = adapt.Value(l); + //don't understand this test. + //if first to last is > 1 radian? are circles parameterize by rotation angle? + //if start and end points are close? if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) { Circle *circle = new Circle(edge); result = circle; @@ -430,7 +436,6 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) result->reversed = true; } - //} // OCC is quite happy with Degree > 3 but QtGui handles only 2,3 } break; case GeomAbs_BSplineCurve: { @@ -438,6 +443,8 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) Generic* gen = NULL; Circle* circ = nullptr; AOC* aoc = nullptr; + TopoDS_Edge circEdge; + bool isArc = false; try { bspline = new BSpline(edge); @@ -447,7 +454,7 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) delete bspline; bspline = nullptr; } else { - TopoDS_Edge circEdge = bspline->asCircle(isArc); + circEdge = bspline->asCircle(isArc); if (!circEdge.IsNull()) { if (isArc) { aoc = new AOC(circEdge); @@ -461,12 +468,15 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) bspline = nullptr; } } else { +// Base::Console().Message("Geom::baseFactory - circEdge is Null\n"); result = bspline; } } break; } - catch (Standard_Failure&) { + catch (const Standard_Failure& e) { + Base::Console().Error("Geom::baseFactory - OCC error - %s - while making spline\n", + e.GetMessageString()); if (bspline != nullptr) { delete bspline; bspline = nullptr; @@ -475,16 +485,39 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge) delete gen; gen = nullptr; } + break; } - } + catch (...) { + Base::Console().Error("Geom::baseFactory - unknown error occurred while making spline\n"); + if (bspline != nullptr) { + delete bspline; + bspline = nullptr; + } + if (gen != nullptr) { + delete gen; + gen = nullptr; + } + break; + } break; + } // end bspline case default: { - Generic *primitive = new Generic(edge); + primitive = new Generic(edge); result = primitive; } break; } + + if ( (primitive != nullptr) && + (primitive != result) ) { + delete primitive; + } + return result; } +bool BaseGeom::validateEdge(TopoDS_Edge edge) +{ + return !DrawUtil::isCrazy(edge); +} Ellipse::Ellipse(const TopoDS_Edge &e) { @@ -515,10 +548,17 @@ AOE::AOE(const TopoDS_Edge &e) : Ellipse(e) gp_Pnt m = c.Value((l+f)/2.0); gp_Pnt ePt = c.Value(l); - gp_Vec v1(m,s); - gp_Vec v2(m,ePt); - gp_Vec v3(0,0,1); - double a = v3.DotCross(v1,v2); + double a; + try { + gp_Vec v1(m,s); + gp_Vec v2(m,ePt); + gp_Vec v3(0,0,1); + a = v3.DotCross(v1,v2); + } + catch (const Standard_Failure& e) { + Base::Console().Error("Geom::AOE::AOE - OCC error - %s - while making AOE in ctor\n", + e.GetMessageString()); + } startAngle = fmod(f,2.0*M_PI); endAngle = fmod(l,2.0*M_PI); @@ -564,34 +604,6 @@ std::string Circle::toString(void) const return baseCSV + ",$$$," + ss.str(); } -//bool Circle::fromCSV(std::string lineSpec) -//{ -// if (lineSpec.length() == 0) { -// Base::Console().Message( "Circle::fromCSV - lineSpec empty\n"); -// return false; -// } - -// std::vector tokens = DrawUtil::tokenize(lineSpec); -// //"baseCSV,$$$,circleCSV" -// if (tokens.size() != 2) { -// Base::Console().Message("CosmeticEdge::fromCSV - tokenize failed - size: %d\n",tokens.size()); -// } - -// BaseGeom::fromCSV(tokens[0]); -// unsigned int maxCells = 4; -// std::vector values = DrawUtil::split(tokens[1]); -// if (values.size() < maxCells) { -// Base::Console().Message( "Circle::fromCSV(%s) invalid CSV entry\n",lineSpec.c_str() ); -// return false; -// } -// double x = atof(values[0].c_str()); -// double y = atof(values[1].c_str()); -// double z = atof(values[2].c_str()); -// center = Base::Vector3d(x,y,z); -// radius = atof(values[3].c_str()); -// return true; -//} - void Circle::Save(Base::Writer &writer) const { BaseGeom::Save(writer); @@ -627,11 +639,11 @@ AOC::AOC(const TopoDS_Edge &e) : Circle(e) double l = c.LastParameter(); gp_Pnt s = c.Value(f); gp_Pnt m = c.Value((l+f)/2.0); - gp_Pnt ePt = c.Value(l); + gp_Pnt ePt = c.Value(l); //if start == end, it isn't an arc! gp_Vec v1(m,s); //vector mid to start gp_Vec v2(m,ePt); //vector mid to end gp_Vec v3(0,0,1); //stdZ - double a = v3.DotCross(v1,v2); + double a = v3.DotCross(v1,v2); //error if v1 = v2? startAngle = fmod(f,2.0*M_PI); endAngle = fmod(l,2.0*M_PI); @@ -733,46 +745,6 @@ std::string AOC::toString(void) const return result; } -//bool AOC::fromCSV(std::string lineSpec) -//{ -//// Base::Console().Message( "AOC::fromCSV(%s)\n", lineSpec.c_str()); -// if (lineSpec.length() == 0) { -// Base::Console().Message( "AOC::fromCSV - lineSpec empty\n"); -// return false; -// } -// std::vector tokens = DrawUtil::tokenize(lineSpec); -// //"(baseCSV,$$$,circleCSV),$$$,AOCCSV" -// // [0] [1] [2] -// if (tokens.size() != 3) { -// Base::Console().Message("CosmeticEdge::fromCSV - tokenize failed - size: %d\n",tokens.size()); -// } - -// Circle::fromCSV(tokens[0] + ",$$$," + tokens[1]); //extra work here. -// unsigned int maxCells = 13; -// std::vector values = DrawUtil::split(tokens[2]); // we are only interested in last token -// if (values.size() < maxCells) { -// Base::Console().Message( "AOC::fromCSV(%s) invalid CSV entry\n",lineSpec.c_str() ); -// return false; -// } -// double x = atof(values[0].c_str()); -// double y = atof(values[1].c_str()); -// double z = atof(values[2].c_str()); -// startPnt = Base::Vector3d(x,y,z); -// x = atof(values[3].c_str()); -// y = atof(values[4].c_str()); -// z = atof(values[5].c_str()); -// endPnt = Base::Vector3d(x,y,z); -// x = atof(values[6].c_str()); -// y = atof(values[7].c_str()); -// z = atof(values[8].c_str()); -// midPnt = Base::Vector3d(x,y,z); -// startAngle = atof(values[9].c_str()); -// endAngle = atof(values[10].c_str()); -// cw = atoi(values[11].c_str()); -// largeArc = atoi(values[12].c_str()); -// return true; -//} - void AOC::Save(Base::Writer &writer) const { Circle::Save(writer); @@ -873,35 +845,6 @@ std::string Generic::toString(void) const return baseCSV + ",$$$," + genericCSV; } -//bool Generic::fromCSV(std::string lineSpec) -//{ - -// std::vector tokens = DrawUtil::tokenize(lineSpec); -// //"baseCSV,$$$,genericCSV" -// if (tokens.size() != 2) { -// Base::Console().Message("Generic::fromCSV - tokenize failed - size: %d\n",tokens.size()); -// } - -// BaseGeom::fromCSV(tokens[0]); -// if (lineSpec.length() == 0) { -// Base::Console().Message( "Generic::fromCSV - lineSpec empty\n"); -// return false; -// } -// std::vector values = DrawUtil::split(tokens[1]); -// if (!values.empty()) { -// double count = atoi(values[0].c_str()); -// points.clear(); -// int i = 0; -// for ( ; i < count; i++) { -// int idx = i * 3; -// double x = atof(values[idx+1].c_str()); -// double y = atof(values[idx+2].c_str()); -// double z = atof(values[idx+3].c_str()); -// points.push_back(Base::Vector3d(x, y, z)); -// } -// } -// return true; -//} void Generic::Save(Base::Writer &writer) const { @@ -1189,99 +1132,105 @@ TopoDS_Edge BSpline::asCircle(bool& arc) gp_Pnt s = c.Value(f); gp_Pnt e = c.Value(l); - arc = !c.IsClosed(); + if (s.IsEqual(e, 0.001)) { //more reliable + arc = false; + } else { + arc = true; + } +// arc = !c.IsClosed(); //reliable? + Handle(Geom_BSplineCurve) spline = c.BSpline(); if (spline->NbPoles() < 5) { //need 5 poles (s-p1-pm-p2-e) for algo return result; //how to do with fewer poles? } - // get three points on curve (non extreme poles) - int nb_poles = spline->NbPoles(); - gp_Pnt p1 = spline->Pole(2); //OCC numbering starts at 1!! - gp_Pnt p2 = spline->Pole(nb_poles-1); - gp_Pnt pm; - if (nb_poles == 5) { - pm = spline->Pole(3); //5 poles => 2.5 => 2 - } else { - pm = spline->Pole(nb_poles / 2); - } - - // project three poles onto the curve - GeomAPI_ProjectPointOnCurve proj1; - GeomAPI_ProjectPointOnCurve proj2; - GeomAPI_ProjectPointOnCurve projm; try { + // get three points on curve (non extreme poles) + int nb_poles = spline->NbPoles(); + gp_Pnt p1 = spline->Pole(2); //OCC numbering starts at 1!! + gp_Pnt p2 = spline->Pole(nb_poles-1); + gp_Pnt pm; + if (nb_poles == 5) { + pm = spline->Pole(3); //5 poles => 2.5 => 2 + } else { + pm = spline->Pole(nb_poles / 2); + } + + // project three poles onto the curve + GeomAPI_ProjectPointOnCurve proj1; + GeomAPI_ProjectPointOnCurve proj2; + GeomAPI_ProjectPointOnCurve projm; proj1.Init(p1, curve, f, l); proj1.Perform(p1); proj2.Init(p2, curve, f, l); proj2.Perform(p2); projm.Init(pm, curve, f, l); projm.Perform(pm); - } - catch(const StdFail_NotDone &e) { - Base::Console().Log("Geometry::asCircle - init: %s\n",e.GetMessageString()); - return result; - } - if ( (proj1.NbPoints() == 0) || - (proj2.NbPoints() == 0) || - (projm.NbPoints() == 0) ) { - return result; - } - gp_Pnt pc1, pc2, pcm; + if ( (proj1.NbPoints() == 0) || + (proj2.NbPoints() == 0) || + (projm.NbPoints() == 0) ) { + return result; + } + gp_Pnt pc1, pc2, pcm; - // get projected points - try { + // get projected points pc1 = proj1.NearestPoint(); pc2 = proj2.NearestPoint(); pcm = projm.NearestPoint(); - } - catch(const StdFail_NotDone &e) { - Base::Console().Log("Geometry::asCircle - nearPoint: %s\n",e.GetMessageString()); - return result; - } - // make 2 circles and find their radii - gce_MakeCirc gce_circ1 = gce_MakeCirc(s,pc1,pcm); //3 point circle - if (gce_circ1.Status() != gce_Done) { - return result; - } - gp_Circ circle1 = gce_circ1.Value(); - double radius1 = circle1.Radius(); - gp_Pnt center1 = circle1.Location(); - Base::Vector3d vc1 = DrawUtil::gpPnt2V3(center1); + // make 2 circles and find their radii + gce_MakeCirc gce_circ1 = gce_MakeCirc(s,pc1,pcm); //3 point circle + if (gce_circ1.Status() != gce_Done) { + return result; + } + gp_Circ circle1 = gce_circ1.Value(); + double radius1 = circle1.Radius(); + gp_Pnt center1 = circle1.Location(); + Base::Vector3d vc1 = DrawUtil::gpPnt2V3(center1); - gce_MakeCirc gce_circ2 = gce_MakeCirc(pcm,pc2,e); - if (gce_circ2.Status() != gce_Done) { - return result; - } - gp_Circ circle2 = gce_circ2.Value(); - double radius2 = circle2.Radius(); - gp_Pnt center2 = circle2.Location(); - Base::Vector3d vc2 = DrawUtil::gpPnt2V3(center2); + gce_MakeCirc gce_circ2 = gce_MakeCirc(pcm,pc2,e); + if (gce_circ2.Status() != gce_Done) { + return result; + } + gp_Circ circle2 = gce_circ2.Value(); + double radius2 = circle2.Radius(); + gp_Pnt center2 = circle2.Location(); + Base::Vector3d vc2 = DrawUtil::gpPnt2V3(center2); - // compare radii & centers - double allowError = 0.001; //mm^-3 good enough for printing - double radius; - Base::Vector3d center; - if ( (DrawUtil::fpCompare(radius2,radius1, allowError)) && - (vc1.IsEqual(vc2,allowError)) ) { - if (arc) { - GC_MakeArcOfCircle makeArc(s,pcm,e); - Handle(Geom_TrimmedCurve) tCurve = makeArc.Value(); - BRepBuilderAPI_MakeEdge newEdge(tCurve); - result = newEdge; - } else { - radius = (radius1 + radius2) / 2.0; - center = (vc1 + vc2) / 2.0; - gp_Pnt gCenter(center.x,center.y,center.z); - gp_Ax2 stdZ(gCenter,gp_Dir(0,0,1)); - gp_Circ newCirc(stdZ,radius); - BRepBuilderAPI_MakeEdge newEdge(newCirc); - result = newEdge; + // compare radii & centers + double allowError = 0.001; //mm^-3 good enough for printing + double radius; + Base::Vector3d center; + if ( (DrawUtil::fpCompare(radius2,radius1, allowError)) && + (vc1.IsEqual(vc2,allowError)) ) { + if (arc) { + GC_MakeArcOfCircle makeArc(s,pcm,e); + Handle(Geom_TrimmedCurve) tCurve = makeArc.Value(); + BRepBuilderAPI_MakeEdge newEdge(tCurve); + result = newEdge; + } else { + radius = (radius1 + radius2) / 2.0; + center = (vc1 + vc2) / 2.0; + gp_Pnt gCenter(center.x,center.y,center.z); + gp_Ax2 stdZ(gCenter,gp_Dir(0,0,1)); + gp_Circ newCirc(stdZ,radius); + BRepBuilderAPI_MakeEdge newEdge(newCirc); + result = newEdge; + } } } - + catch (const Standard_Failure& e) { + Base::Console().Log("Geom::asCircle - OCC error - %s - while approx spline as circle\n", + e.GetMessageString()); + TopoDS_Edge nullReturn; + result = nullReturn; + } + catch (...) { + Base::Console().Log("Geom::asCircle - unknown error occurred while approx spline as circle\n"); + TopoDS_Edge nullReturn; + result = nullReturn; + } return result; } @@ -1472,14 +1421,6 @@ std::string Vertex::getTagAsString(void) const return tmp; } -//void Vertex::assignTag(const TechDraw::Vertex* v) -//{ -// if(v->getTypeId() == this->getTypeId()) -// this->tag = v->tag; -// else -// throw Base::TypeError("Vertex tag can not be assigned as types do not match."); -//} - void Vertex::dump(const char* title) { Base::Console().Message("TD::Vertex - %s - point: %s vis: %d cosmetic: %d cosLink: %d cosTag: %s\n", diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index 98a4a04573..a7d9ead6a0 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -106,6 +106,7 @@ class TechDrawExport BaseGeom Base::Vector3d nearPoint(Base::Vector3d p); Base::Vector3d nearPoint(const BaseGeom* p); static BaseGeom* baseFactory(TopoDS_Edge edge); + static bool validateEdge(TopoDS_Edge edge); bool closed(void); BaseGeom* copy(); std::string dump(); diff --git a/src/Mod/TechDraw/App/GeometryObject.cpp b/src/Mod/TechDraw/App/GeometryObject.cpp index 4a77c5a49b..1ff6f2697b 100644 --- a/src/Mod/TechDraw/App/GeometryObject.cpp +++ b/src/Mod/TechDraw/App/GeometryObject.cpp @@ -480,7 +480,7 @@ void GeometryObject::extractGeometry(edgeClass category, bool hlrVisible) //! update edgeGeom and vertexGeom from Compound of edges void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool hlrVisible) { -// Base::Console().Message("GO::addGeomFromCompound()\n"); +// Base::Console().Message("GO::addGeomFromCompound(%d, %d)\n", category, hlrVisible); if(edgeCompound.IsNull()) { Base::Console().Log("TechDraw::GeometryObject::addGeomFromCompound edgeCompound is NULL\n"); return; // There is no OpenCascade Geometry to be calculated @@ -492,19 +492,25 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca for ( ; edges.More(); edges.Next(),i++) { const TopoDS_Edge& edge = TopoDS::Edge(edges.Current()); if (edge.IsNull()) { - //Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i); + Base::Console().Log("GO::addGeomFromCompound - edge: %d is NULL\n",i); continue; } if (DrawUtil::isZeroEdge(edge)) { - Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is zeroEdge\n",i); + Base::Console().Log("GO::addGeomFromCompound - edge: %d is zeroEdge\n",i); + continue; + } + if (DrawUtil::isCrazy(edge)) { + Base::Console().Log("GO::addGeomFromCompound - edge: %d is crazy\n",i); continue; } base = BaseGeom::baseFactory(edge); if (base == nullptr) { Base::Console().Log("Error - GO::addGeomFromCompound - baseFactory failed for edge: %d\n",i); - throw Base::ValueError("GeometryObject::addGeomFromCompound - baseFactory failed"); + continue; +// throw Base::ValueError("GeometryObject::addGeomFromCompound - baseFactory failed"); } + base->source(0); //object geometry base->sourceIndex(i-1); base->classOfEdge = category; diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index 023949b5f1..1ac77a5b45 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -148,6 +148,10 @@ QPainterPath QGIViewPart::geomToPainterPath(TechDraw::BaseGeom *baseGeom, double Q_UNUSED(rot); QPainterPath path; + if (baseGeom == nullptr) { + return path; + } + switch(baseGeom->geomType) { case CIRCLE: { TechDraw::Circle *geom = static_cast(baseGeom);