diff --git a/src/Mod/TechDraw/App/DimensionFormatter.cpp b/src/Mod/TechDraw/App/DimensionFormatter.cpp index d03143c7cc..c303091058 100644 --- a/src/Mod/TechDraw/App/DimensionFormatter.cpp +++ b/src/Mod/TechDraw/App/DimensionFormatter.cpp @@ -58,6 +58,8 @@ std::string DimensionFormatter::formatValue(qreal value, int partial, bool isDim) { +// Base::Console().Message("DF::formatValue() - %s isRestoring: %d\n", +// m_dimension->getNameInDocument(), m_dimension->isRestoring()); bool angularMeasure = false; QLocale loc; @@ -129,7 +131,8 @@ std::string DimensionFormatter::formatValue(qreal value, } if (isTooSmall(userVal, formatSpecifier)) { - Base::Console().Warning("Dimension value is too small for format specifier: %s\n", qPrintable(formatSpecifier)); + Base::Console().Warning("Dimension %s value %.6f is too small for format specifier: %s\n", + m_dimension->getNameInDocument(), userVal, qPrintable(formatSpecifier)); } formattedValue = formatValueToSpec(userVal, formatSpecifier); @@ -398,7 +401,7 @@ bool DimensionFormatter::isTooSmall(double value, QString formatSpec) QString decimalGroup = rxMatch.captured(1); int factor = decimalGroup.toInt(); double minValue = pow(10.0, -factor); - if (value < minValue) { + if (std::fabs(value) < minValue) { return true; } } else { diff --git a/src/Mod/TechDraw/App/DimensionReferences.cpp b/src/Mod/TechDraw/App/DimensionReferences.cpp index 703ec054d7..d7bbf24b6d 100644 --- a/src/Mod/TechDraw/App/DimensionReferences.cpp +++ b/src/Mod/TechDraw/App/DimensionReferences.cpp @@ -65,6 +65,19 @@ TopoDS_Shape ReferenceEntry::getGeometry() const return shape.getSubShape(getSubName().c_str()); } +std::string ReferenceEntry::getSubName(bool longForm) const +{ + if (longForm) { + return m_subName; + } + std::string workingSubName(m_subName); + size_t lastDot = workingSubName.rfind('.'); + if (lastDot != std::string::npos) { + workingSubName = workingSubName.substr(lastDot + 1); + } + return workingSubName; +} + std::string ReferenceEntry::geomType() const { return DrawUtil::getGeomTypeFromName(getSubName()); diff --git a/src/Mod/TechDraw/App/DimensionReferences.h b/src/Mod/TechDraw/App/DimensionReferences.h index 34292a597e..9607e7cbdf 100644 --- a/src/Mod/TechDraw/App/DimensionReferences.h +++ b/src/Mod/TechDraw/App/DimensionReferences.h @@ -54,7 +54,7 @@ public: App::DocumentObject* getObject() const { return m_object; } void setObject(App::DocumentObject* docObj) { m_object = docObj; } - std::string getSubName() const { return m_subName; } + std::string getSubName(bool longForm = false) const; void setSubName(std::string subName) { m_subName = subName; } TopoDS_Shape getGeometry() const; std::string geomType() const; diff --git a/src/Mod/TechDraw/App/DrawViewDimension.cpp b/src/Mod/TechDraw/App/DrawViewDimension.cpp index 79f9cd8d0a..7e71cdd141 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.cpp +++ b/src/Mod/TechDraw/App/DrawViewDimension.cpp @@ -267,7 +267,7 @@ void DrawViewDimension::onChanged(const App::Property* prop) } return; } else if (prop == &OverTolerance) { -= // if EqualTolerance set negated overtolerance for untertolerance + // if EqualTolerance set negated overtolerance for untertolerance if (EqualTolerance.getValue()) { UnderTolerance.setValue(-1.0 * OverTolerance.getValue()); UnderTolerance.setUnit(OverTolerance.getUnit()); @@ -567,8 +567,15 @@ pointPair DrawViewDimension::getPointsOneEdge(ReferenceVector references) //TODO: Notify if not straight line Edge? //this is a 2d object (a DVP + subelements) TechDraw::BaseGeomPtr geom = getViewPart()->getGeomByIndex(iSubelement); - if (!geom || geom->geomType != TechDraw::GeomType::GENERIC) { - throw Base::RuntimeError("Missing geometry for dimension"); + if (!geom) { + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " can not find geometry for 2d reference (1)"; + throw Base::RuntimeError(ssMessage.str()); + } + if (geom->geomType != TechDraw::GeomType::GENERIC) { + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " 2d reference is a " << geom->geomTypeName(); + throw Base::RuntimeError(ssMessage.str()); } TechDraw::GenericPtr generic = std::static_pointer_cast(geom); return { generic->points[0], generic->points[1] }; @@ -600,14 +607,16 @@ pointPair DrawViewDimension::getPointsTwoEdges(ReferenceVector references) // Base::Console().Message("DVD::getPointsTwoEdges() - %s\n", getNameInDocument()); App::DocumentObject* refObject = references.front().getObject(); int iSubelement0 = DrawUtil::getIndexFromName(references.at(0).getSubName()); - int iSubelement1 = DrawUtil::getIndexFromName(references.at(0).getSubName()); + int iSubelement1 = DrawUtil::getIndexFromName(references.at(1).getSubName()); if (refObject->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) && !references.at(0).getSubName().empty()) { //this is a 2d object (a DVP + subelements) TechDraw::BaseGeomPtr geom0 = getViewPart()->getGeomByIndex(iSubelement0); TechDraw::BaseGeomPtr geom1 = getViewPart()->getGeomByIndex(iSubelement1); if (!geom0 || !geom1) { - throw Base::RuntimeError("Missing geometry for dimension"); + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " can not find geometry for 2d reference (2)"; + throw Base::RuntimeError(ssMessage.str()); } return closestPoints(geom0->occEdge, geom1->occEdge); } @@ -640,8 +649,11 @@ pointPair DrawViewDimension::getPointsTwoVerts(ReferenceVector references) TechDraw::VertexPtr v0 = getViewPart()->getProjVertexByIndex(iSubelement0); TechDraw::VertexPtr v1 = getViewPart()->getProjVertexByIndex(iSubelement1); if (!v0 || !v1) { - throw Base::RuntimeError("Missing geometry for dimension"); + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " can not find geometry for 2d reference (3)"; + throw Base::RuntimeError(ssMessage.str()); } + return { v0->pnt, v1->pnt }; } @@ -670,7 +682,7 @@ pointPair DrawViewDimension::getPointsEdgeVert(ReferenceVector references) // Base::Console().Message("DVD::getPointsEdgeVert() - %s\n", getNameInDocument()); App::DocumentObject* refObject = references.front().getObject(); int iSubelement0 = DrawUtil::getIndexFromName(references.at(0).getSubName()); - int iSubelement1 = DrawUtil::getIndexFromName(references.at(0).getSubName()); + int iSubelement1 = DrawUtil::getIndexFromName(references.at(1).getSubName()); if (refObject->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) && !references.at(0).getSubName().empty()) { //this is a 2d object (a DVP + subelements) @@ -684,7 +696,7 @@ pointPair DrawViewDimension::getPointsEdgeVert(ReferenceVector references) vertex = getViewPart()->getProjVertexByIndex(iSubelement0); } if (!vertex || !edge) { - throw Base::RuntimeError("Missing geometry for dimension"); + throw Base::RuntimeError("Missing geometry for dimension (4)"); } return closestPoints(edge->occEdge, vertex->occVertex); } @@ -715,8 +727,9 @@ arcPoints DrawViewDimension::getArcParameters(ReferenceVector references) //this is a 2d object (a DVP + subelements) TechDraw::BaseGeomPtr geom = getViewPart()->getGeomByIndex(iSubelement); if (!geom) { - Base::Console().Error("DVD - %s - 2D references are corrupt (1)\n",getNameInDocument()); - return arcPoints(); + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " can not find geometry for 2d reference (4)"; + throw Base::RuntimeError(ssMessage.str()); } return arcPointsFromBaseGeom(getViewPart()->getGeomByIndex(iSubelement)); } @@ -820,8 +833,9 @@ arcPoints DrawViewDimension::arcPointsFromBaseGeom(TechDraw::BaseGeomPtr base) throw Base::RuntimeError("Bad BSpline geometry for arc dimension"); } } else { - Base::Console().Log("Error: DVD - %s - 2D references are corrupt\n", getNameInDocument()); - throw Base::RuntimeError("Bad geometry for arc dimension"); + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " 2d reference is a " << base->geomTypeName(); + throw Base::RuntimeError(ssMessage.str()); } return pts; } @@ -922,13 +936,19 @@ anglePoints DrawViewDimension::getAnglePointsTwoEdges(ReferenceVector references TechDraw::BaseGeomPtr geom0 = getViewPart()->getGeomByIndex(iSubelement0); TechDraw::BaseGeomPtr geom1 = getViewPart()->getGeomByIndex(iSubelement1); if (!geom0 || !geom1) { - throw Base::RuntimeError("Missing geometry for dimension"); + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " can not find geometry for 2d reference (5)"; + throw Base::RuntimeError(ssMessage.str()); } - if (!geom0 || geom0->geomType != TechDraw::GeomType::GENERIC) { - throw Base::RuntimeError("Missing geometry for dimension"); + if (geom0->geomType != TechDraw::GeomType::GENERIC) { + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " first 2d reference is a " << geom0->geomTypeName(); + throw Base::RuntimeError(ssMessage.str()); } - if (!geom1 || geom1->geomType != TechDraw::GeomType::GENERIC) { - throw Base::RuntimeError("Missing geometry for dimension"); + if (geom1->geomType != TechDraw::GeomType::GENERIC) { + std::stringstream ssMessage; + ssMessage << getNameInDocument() << " second 2d reference is a " << geom0->geomTypeName(); + throw Base::RuntimeError(ssMessage.str()); } TechDraw::GenericPtr generic0 = std::static_pointer_cast(geom0); TechDraw::GenericPtr generic1 = std::static_pointer_cast(geom1); @@ -1128,6 +1148,34 @@ ReferenceVector DrawViewDimension::getEffectiveReferences() const return effectiveRefs; } +//return the 2d references as a ReferenceVector +ReferenceVector DrawViewDimension::getReferences2d() const +{ + const std::vector& objects = References2D.getValues(); + const std::vector& subElements = References2D.getSubValues(); + ReferenceVector refs2d; + int refCount = objects.size(); + for (int i = 0; i < refCount; i++) { + ReferenceEntry ref(objects.at(i), subElements.at(i)); + refs2d.push_back(ref); + } + return refs2d; +} + +//return the 3d references as a ReferenceVector +ReferenceVector DrawViewDimension::getReferences3d() const +{ + const std::vector& objects3d = References3D.getValues(); + const std::vector& subElements3d = References3D.getSubValues(); + ReferenceVector refs3d; + int refCount = objects3d.size(); + for (int i = 0; i < refCount; i++) { + ReferenceEntry ref(objects3d.at(i), subElements3d.at(i)); + refs3d.push_back(ref); + } + return refs3d; +} + //what configuration of references do we have - Vertex-Vertex, Edge-Vertex, Edge, ... int DrawViewDimension::getRefType() const { diff --git a/src/Mod/TechDraw/App/DrawViewDimension.h b/src/Mod/TechDraw/App/DrawViewDimension.h index 79534682b9..36d7008706 100644 --- a/src/Mod/TechDraw/App/DrawViewDimension.h +++ b/src/Mod/TechDraw/App/DrawViewDimension.h @@ -139,6 +139,8 @@ enum DimensionType { void setReferences2d(ReferenceVector refs); void setReferences3d(ReferenceVector refs); + ReferenceVector getReferences2d() const; + ReferenceVector getReferences3d() const; void setAll3DMeasurement(); void clear3DMeasurements(); diff --git a/src/Mod/TechDraw/App/Geometry.cpp b/src/Mod/TechDraw/App/Geometry.cpp index 14d59bf0b1..2e779aa841 100644 --- a/src/Mod/TechDraw/App/Geometry.cpp +++ b/src/Mod/TechDraw/App/Geometry.cpp @@ -415,6 +415,24 @@ bool BaseGeom::closed() return false; } +//keep this in sync with enum GeomType +std::string BaseGeom::geomTypeName() +{ + std::vector typeNames { + "NotDefined", + "Circle", + "ArcOfCircle", + "Ellipse", + "ArcOfEllipse", + "Bezier", + "BSpline", + "Line", //why was this ever called "Generic"? + "Unknown" } ; + if (geomType >= typeNames.size()) { + return "Unknown"; + } + return typeNames.at(geomType); +} //! Convert 1 OCC edge into 1 BaseGeom (static factory method) BaseGeomPtr BaseGeom::baseFactory(TopoDS_Edge edge) diff --git a/src/Mod/TechDraw/App/Geometry.h b/src/Mod/TechDraw/App/Geometry.h index 344ecccb13..f6eefe1a80 100644 --- a/src/Mod/TechDraw/App/Geometry.h +++ b/src/Mod/TechDraw/App/Geometry.h @@ -133,6 +133,8 @@ class TechDrawExport BaseGeom : public std::enable_shared_from_this boost::uuids::uuid getTag() const; virtual std::string getTagAsString() const; + std::string geomTypeName(); + private: void intersectionLL(TechDraw::BaseGeomPtr geom1, TechDraw::BaseGeomPtr geom2, diff --git a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp index 73296d46d4..7aa067cc8e 100644 --- a/src/Mod/TechDraw/Gui/CommandCreateDims.cpp +++ b/src/Mod/TechDraw/Gui/CommandCreateDims.cpp @@ -612,6 +612,7 @@ void execDistance(Gui::Command* cmd) acceptableGeometry, minimumCounts, acceptableDimensionGeometrys); + if ( geometryRefs2d == TechDraw::isInvalid ) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), @@ -628,6 +629,7 @@ void execDistance(Gui::Command* cmd) acceptableGeometry, minimumCounts, acceptableDimensionGeometrys); + if ( geometryRefs3d == TechDraw::isInvalid ) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Incorrect Selection"), @@ -699,7 +701,7 @@ void execDistanceX(Gui::Command* cmd) //Define the geometric configuration required for a length dimension StringVector acceptableGeometry( { "Edge", "Vertex" } ); std::vector minimumCounts( { 1, 2 } ); - std::vector acceptableDimensionGeometrys( { isHorizontal } ); + std::vector acceptableDimensionGeometrys( { isHorizontal, isDiagonal } ); //what 2d geometry configuration did we receive? DimensionGeometryType geometryRefs2d = validateDimSelection(references2d, @@ -794,7 +796,7 @@ void execDistanceY(Gui::Command* cmd) //Define the geometric configuration required for a length dimension StringVector acceptableGeometry( { "Edge", "Vertex" } ); std::vector minimumCounts( { 1, 2 } ); - std::vector acceptableDimensionGeometrys( { isVertical } ); + std::vector acceptableDimensionGeometrys( { isVertical, isDiagonal } ); //what 2d geometry configuration did we receive? DimensionGeometryType geometryRefs2d = validateDimSelection(references2d, @@ -1632,12 +1634,9 @@ DrawViewDimension* dimensionMaker(TechDraw::DrawViewPart* dvp, Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('TechDraw::DrawViewDimension', '%s')", dimName.c_str()); Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Type = '%s'", dimName.c_str() ,dimType.c_str()); - std::string measureType("True"); - if (references3d.empty()) { - measureType = "Projected"; - } + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MeasureType = '%s'", dimName.c_str(), - measureType.c_str()); + "Projected"); dim = dynamic_cast(dvp->getDocument()->getObject(dimName.c_str())); if (!dim) { diff --git a/src/Mod/TechDraw/Gui/DimensionValidators.cpp b/src/Mod/TechDraw/Gui/DimensionValidators.cpp index 7422b712eb..dcbbbc75eb 100644 --- a/src/Mod/TechDraw/Gui/DimensionValidators.cpp +++ b/src/Mod/TechDraw/Gui/DimensionValidators.cpp @@ -459,23 +459,25 @@ DimensionGeometryType TechDraw::isValidMultiEdge(ReferenceVector refs) return isInvalid; } - //must be an extent? - if (refs.size() > 2) { - return isMultiEdge; - } - auto objFeat0( dynamic_cast(refs.at(0).getObject())); if ( !objFeat0 ) { //probably redundant throw Base::RuntimeError("Logic error in isValidMultiEdge"); } - //they both must start with "Edge" - if(TechDraw::DrawUtil::getGeomTypeFromName(refs.at(0).getSubName()) != "Edge" || - TechDraw::DrawUtil::getGeomTypeFromName(refs.at(1).getSubName()) != "Edge") { - return isInvalid; + //they all must start with "Edge" + for (auto& ref : refs) { + if(TechDraw::DrawUtil::getGeomTypeFromName(ref.getSubName()) != "Edge" ) { + return isInvalid; + } } + if (refs.size() > 2) { + //many edges, must be an extent? + return isMultiEdge; + } + + //exactly 2 edges. could be angle, could be distance int GeoId0( TechDraw::DrawUtil::getIndexFromName(refs.at(0).getSubName()) ); int GeoId1( TechDraw::DrawUtil::getIndexFromName(refs.at(1).getSubName()) ); TechDraw::BaseGeomPtr geom0 = objFeat0->getGeomByIndex(GeoId0); diff --git a/src/Mod/TechDraw/Gui/TaskDimRepair.cpp b/src/Mod/TechDraw/Gui/TaskDimRepair.cpp index e01ea5e785..3f70901f67 100644 --- a/src/Mod/TechDraw/Gui/TaskDimRepair.cpp +++ b/src/Mod/TechDraw/Gui/TaskDimRepair.cpp @@ -49,7 +49,6 @@ #include #include -#include "PreferencesGui.h" #include "DimensionValidators.h" #include "TaskDimRepair.h" #include @@ -68,6 +67,13 @@ TaskDimRepair::TaskDimRepair(TechDraw::DrawViewDimension* inDvd, { ui->setupUi(this); + if (m_references2d.size() == 1 && + m_references2d.front().getSubName().empty() && + m_references3d.empty()) { + //the entry in references2d is a spurious View reference (from getReferencesFromSelection), + // not a geometry reference, so we treat it as empty + m_references2d.clear(); + } connect(ui->pbSelection, SIGNAL(clicked(bool)), this, SLOT(slotUseSelection())); saveDimState(); @@ -105,7 +111,7 @@ void TaskDimRepair::setUiPrimary() if (!m_references3d.empty()) { references3d = m_references3d; } else if (!objs3d.empty()) { - references3d = m_dim->getEffectiveReferences(); + references3d = m_dim->getReferences3d(); } loadTableWidget(ui->twReferences3d, references3d); } @@ -115,21 +121,18 @@ void TaskDimRepair::saveDimState() m_saveMeasureType = m_dim->MeasureType.getValue(); m_saveDimType = m_dim->Type.getValue(); m_dimType = m_dim->Type.getValue(); - m_saveObjs3d = m_dim->References3D.getValues(); - m_saveSubs3d = m_dim->References3D.getSubValues(); - m_saveDvp = static_cast(m_dim->References2D.getValues().front()); - m_saveSubs2d = m_dim->References2D.getSubValues(); + m_saveRefs3d = m_dim->getReferences3d(); + m_saveRefs2d = m_dim->getReferences2d(); + m_saveDvp = m_dim->getViewPart(); } //restore the start conditions void TaskDimRepair::restoreDimState() { // Base::Console().Message("TDR::restoreDimState()\n"); - if (m_dim != nullptr) { - std::vector objs2d(m_saveSubs2d.size()); - std::iota(objs2d.begin(), objs2d.end(), m_saveDvp); - m_dim->References2D.setValues(objs2d, m_saveSubs2d); - m_dim->References3D.setValues(m_saveObjs3d, m_saveSubs3d); + if (m_dim) { + m_dim->setReferences2d(m_saveRefs2d); + m_dim->setReferences3d(m_saveRefs3d); } } @@ -137,6 +140,7 @@ void TaskDimRepair::restoreDimState() //use the current selection to replace the references in dim void TaskDimRepair::slotUseSelection() { +// Base::Console().Message("TDR::slotUseSelection()\n"); const std::vector dimObjects = Gui::Selection().getObjectsOfType(TechDraw::DrawViewDimension::getClassTypeId()); if (dimObjects.empty()) { //selection does not include a dimension, so we need to add our dimension to keep the @@ -256,29 +260,24 @@ void TaskDimRepair::fillList(QListWidget* lwItems, std::vector labe } void TaskDimRepair::replaceReferences() { - if (m_dim) { +// Base::Console().Message("TDR::replaceReferences() - refs2d: %d refs3d %d\n", m_references2d.size(), m_references3d.size()); + if (!m_dim) { + return; + } + if (!m_references2d.empty()) { m_dim->setReferences2d(m_references2d); + } + if (!m_references3d.empty()) { m_dim->setReferences3d(m_references3d); } } -void TaskDimRepair::updateTypes() -{ - if (m_references3d.empty()) { - m_dim->MeasureType.setValue("Projected"); - } else { - m_dim->MeasureType.setValue("True"); - } - m_dim->Type.setValue(m_dimType); -} - - bool TaskDimRepair::accept() { // Base::Console().Message("TDR::accept()\n"); Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()"); replaceReferences(); - updateTypes(); + m_dim->Type.setValue(m_dimType); m_dim->recomputeFeature(); return true; } diff --git a/src/Mod/TechDraw/Gui/TaskDimRepair.h b/src/Mod/TechDraw/Gui/TaskDimRepair.h index 6b68a7c68d..308f8aae02 100644 --- a/src/Mod/TechDraw/Gui/TaskDimRepair.h +++ b/src/Mod/TechDraw/Gui/TaskDimRepair.h @@ -65,7 +65,6 @@ protected: void setUiPrimary(); void replaceReferences(); - void updateTypes(); void updateUi(); void fillList(QListWidget* lwItems, std::vector labels, std::vector names); void loadTableWidget(QTableWidget* tw, TechDraw::ReferenceVector refs); @@ -82,9 +81,8 @@ private: long int m_saveMeasureType; long int m_saveDimType; TechDraw::DrawViewPart* m_saveDvp; - std::vector m_saveSubs2d; - std::vector m_saveObjs3d; - std::vector m_saveSubs3d; + TechDraw::ReferenceVector m_saveRefs2d; + TechDraw::ReferenceVector m_saveRefs3d; }; class TaskDlgDimReference : public Gui::TaskView::TaskDialog