[TD]corrupt dim reference detect and correct

This commit is contained in:
wandererfan
2023-03-13 19:01:31 -04:00
committed by WandererFan
parent 7fd12f8454
commit b9fa9cb33e
16 changed files with 859 additions and 64 deletions

View File

@@ -87,6 +87,7 @@ using Import::ImpExpDxfWrite;
using TechDraw::ProjectionAlgos;
using namespace std;
using namespace Part;
namespace TechDraw {
@@ -271,7 +272,7 @@ private:
}
else {
for (auto& w : sortedWires) {
PyObject* wire = new TopoShapeWirePy(new TopoShape(w));
PyObject* wire = new TopoShapeWirePy(new Part::TopoShape(w));
result.append(Py::asObject(wire));
}
}

View File

@@ -24,6 +24,7 @@ set(TechDrawLIBS
Part
Spreadsheet
Import
PartDesign
)
if(FREECAD_QT_MAJOR_VERSION EQUAL 5)
@@ -114,6 +115,8 @@ SET(Draw_SRCS
DimensionReferences.h
DimensionFormatter.cpp
DimensionFormatter.h
GeometryMatcher.cpp
GeometryMatcher.h
DrawViewBalloon.cpp
DrawViewBalloon.h
DrawViewSection.cpp

View File

@@ -53,10 +53,8 @@ void pointPair::move(Base::Vector3d offset)
// project the points onto the dvp's paper plane. Points are still in R3 coords.
void pointPair::project(DrawViewPart* dvp)
{
Base::Vector3d normal = DrawUtil::toVector3d(dvp->getProjectionCS().Direction());
Base::Vector3d stdOrigin(0.0, 0.0, 0.0);
m_first = m_first.ProjectToPlane(stdOrigin, normal) * dvp->getScale();
m_second = m_second.ProjectToPlane(stdOrigin, normal) * dvp->getScale();
m_first = dvp->projectPoint(m_first) * dvp->getScale();
m_second = dvp->projectPoint(m_second) * dvp->getScale();
}
// map the points onto the dvp's XY coordinate system
@@ -111,10 +109,8 @@ void anglePoints::move(Base::Vector3d offset)
// project the points onto the dvp's paper plane. Points are still in R3 coords.
void anglePoints::project(DrawViewPart* dvp)
{
Base::Vector3d normal = DrawUtil::toVector3d(dvp->getProjectionCS().Direction());
Base::Vector3d stdOrigin(0.0, 0.0, 0.0);
m_ends.project(dvp);
m_vertex = m_vertex.ProjectToPlane(stdOrigin, normal) * dvp->getScale();
m_vertex = dvp->projectPoint(m_vertex) * dvp->getScale();
}
// map the points onto the dvp's XY coordinate system
@@ -187,14 +183,12 @@ void arcPoints::move(Base::Vector3d offset)
void arcPoints::project(DrawViewPart* dvp)
{
radius = radius * dvp->getScale();
Base::Vector3d normal = DrawUtil::toVector3d(dvp->getProjectionCS().Direction());
Base::Vector3d stdOrigin(0.0, 0.0, 0.0);
center = center.ProjectToPlane(stdOrigin, normal) * dvp->getScale();
onCurve.first(onCurve.first().ProjectToPlane(stdOrigin, normal) * dvp->getScale());
onCurve.second(onCurve.second().ProjectToPlane(stdOrigin, normal) * dvp->getScale());
arcEnds.first(arcEnds.first().ProjectToPlane(stdOrigin, normal) * dvp->getScale());
arcEnds.second(arcEnds.second().ProjectToPlane(stdOrigin, normal) * dvp->getScale());
midArc = midArc.ProjectToPlane(stdOrigin, normal) * dvp->getScale();
center = dvp->projectPoint(center) * dvp->getScale();
onCurve.first(dvp->projectPoint(onCurve.first()) * dvp->getScale());
onCurve.second(dvp->projectPoint(onCurve.second()) * dvp->getScale());
arcEnds.first(dvp->projectPoint(arcEnds.first()) * dvp->getScale());
arcEnds.second(dvp->projectPoint(arcEnds.second()) * dvp->getScale());
midArc = dvp->projectPoint(midArc) * dvp->getScale();
}
void arcPoints::mapToPage(DrawViewPart* dvp)

View File

@@ -25,18 +25,29 @@
# include <TopoDS_Shape.hxx>
#endif
#include <BRep_Tool.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopExp.hxx>
#include <App/GeoFeature.h>
#include <Base/Console.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/PartDesign/App/Body.h>
#include <Mod/PartDesign/App/Feature.h>
#include "DimensionReferences.h"
#include "DrawUtil.h"
#include "DrawViewPart.h"
#include "GeometryObject.h"
using namespace TechDraw;
using DU = DrawUtil;
TopoDS_Shape ReferenceEntry::getGeometry() const
{
// Base::Console().Message("RE::getGeometry()\n");
if ( getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) ) {
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
std::string gType = geomType();
@@ -50,6 +61,7 @@ TopoDS_Shape ReferenceEntry::getGeometry() const
auto fgeom = dvp->getFace(getSubName());
return fgeom->toOccFace();
}
//Base::Console().Message("RE::getGeometry - returns null shape! - gType: %s\n", gType.c_str());
return TopoDS_Shape();
}
@@ -62,6 +74,7 @@ TopoDS_Shape ReferenceEntry::getGeometry() const
if (getSubName().empty()) {
return shape.getShape();
}
// TODO: what happens if the subelement is no longer present?
return shape.getSubShape(getSubName().c_str());
}
@@ -78,6 +91,58 @@ std::string ReferenceEntry::getSubName(bool longForm) const
return workingSubName;
}
App::DocumentObject* ReferenceEntry::getObject() const
{
// For PartDesign objects, when the reference is created from a selection,
// the SelectionObject is a Feature within the Body.
PartDesign::Body* pdBody = PartDesign::Body::findBodyOf(m_object);
if (pdBody && pdBody->Tip.getValue()) {
return pdBody->Tip.getValue();
}
return m_object;
}
Part::TopoShape ReferenceEntry::asTopoShape()
{
// Base::Console().Message("RE::asTopoShape()\n");
TopoDS_Shape geom = getGeometry();
if (geom.ShapeType() == TopAbs_VERTEX) {
TopoDS_Vertex vert = TopoDS::Vertex(geom);
return asTopoShapeVertex(vert);
} else if (geom.ShapeType() == TopAbs_EDGE) {
TopoDS_Edge edge = TopoDS::Edge(geom);
return asTopoShapeEdge(edge);
} else {
throw Base::RuntimeError("Dimension Reference has unsupported geometry");
}
return Part::TopoShape();
}
Part::TopoShape ReferenceEntry::asTopoShapeVertex(TopoDS_Vertex vert)
{
Base::Vector3d point = DU::toVector3d(BRep_Tool::Pnt(vert));
if (!is3d()) {
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
point = point / dvp->getScale();
}
BRepBuilderAPI_MakeVertex mkVert(DU::togp_Pnt(point));
return Part::TopoShape(mkVert.Vertex());
}
Part::TopoShape ReferenceEntry::asTopoShapeEdge(TopoDS_Edge edge)
{
// Base::Console().Message("RE::asTopoShapeEdge()\n");
TopoDS_Edge unscaledEdge = edge;
if (!is3d()) {
// 2d reference - projected and scaled. scale might have changed, so we need to unscale
TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
TopoDS_Shape unscaledShape = TechDraw::scaleShape(edge, 1.0 / dvp->getScale());
unscaledEdge = TopoDS::Edge(unscaledShape);
}
return Part::TopoShape(unscaledEdge);
}
std::string ReferenceEntry::geomType() const
{
return DrawUtil::getGeomTypeFromName(getSubName());
@@ -87,3 +152,12 @@ bool ReferenceEntry::isWholeObject() const
{
return getSubName().empty();
}
bool ReferenceEntry::is3d() const
{
if ( getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) ) {
return false;
}
return true;
}

View File

@@ -29,13 +29,21 @@
#include <vector>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <Mod/Part/App/TopoShape.h>
namespace App
{
class DocumentObject;
}
namespace Part
{
class TopoShape;
}
namespace TechDraw
{
@@ -53,7 +61,7 @@ public:
}
~ReferenceEntry() = default;
App::DocumentObject* getObject() const { return m_object; }
App::DocumentObject* getObject() const;
void setObject(App::DocumentObject* docObj) { m_object = docObj; }
std::string getSubName(bool longForm = false) const;
void setSubName(std::string subName) { m_subName = subName; }
@@ -61,8 +69,13 @@ public:
std::string geomType() const;
bool isWholeObject() const;
Part::TopoShape asTopoShape();
Part::TopoShape asTopoShapeVertex(TopoDS_Vertex vert);
Part::TopoShape asTopoShapeEdge(TopoDS_Edge edge);
bool is3d() const;
private:
bool is3d();
App::DocumentObject* m_object;
std::string m_subName;
};

View File

@@ -55,7 +55,11 @@
#include <Base/Quantity.h>
#include <Base/Tools.h>
#include <Base/UnitsApi.h>
#include <Mod/Measure/App/Measurement.h>
#include <Mod/Part/App/Geometry.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/TechDraw/App/DrawViewDimensionPy.h> // generated from DrawViewDimensionPy.xml
#include "DrawViewDimension.h"
@@ -63,10 +67,12 @@
#include "DrawUtil.h"
#include "DrawViewPart.h"
#include "Geometry.h"
#include "GeometryMatcher.h"
#include "Preferences.h"
using namespace TechDraw;
using namespace Part;
using DU = DrawUtil;
//===========================================================================
// DrawViewDimension
@@ -135,6 +141,9 @@ DrawViewDimension::DrawViewDimension()
ADD_PROPERTY_TYPE(LineAngle, (0.0), "Override", App::Prop_Output, "Dimension line angle");
ADD_PROPERTY_TYPE(ExtensionAngle, (0.0), "Override", App::Prop_Output, "Extension line angle");
ADD_PROPERTY_TYPE(SavedGeometry, () ,"References",(App::PropertyType)(App::Prop_None),"Reference Geometry");
SavedGeometry.setOrderRelevant(true);
// hide the DrawView properties that don't apply to Dimensions
ScaleType.setStatus(App::Property::ReadOnly, true);
ScaleType.setStatus(App::Property::Hidden, true);
@@ -158,7 +167,8 @@ DrawViewDimension::DrawViewDimension()
resetAngular();
resetArc();
m_hasGeometry = false;
m_formatter = new DimensionFormatter(this);
m_matcher = new GeometryMatcher(this);
m_referencesCorrect = true;
}
DrawViewDimension::~DrawViewDimension()
@@ -166,6 +176,7 @@ DrawViewDimension::~DrawViewDimension()
delete measurement;
measurement = nullptr;
delete m_formatter;
delete m_matcher;
}
void DrawViewDimension::resetLinear()
@@ -208,14 +219,19 @@ void DrawViewDimension::onChanged(const App::Property* prop)
return;
}
if (prop == &References3D) {//have to rebuild the Measurement object
clear3DMeasurements(); //Measurement object
if (prop == &References2D) {
updateSavedGeometry();
} else if (prop == &References3D) {
// remove the old measurement object
clear3DMeasurements();
if (!(References3D.getValues()).empty()) {
// rebuild the Measurement object
setAll3DMeasurement();
}
else if (MeasureType.isValue("True")) {//empty 3dRefs, but True
MeasureType.touch(); //run MeasureType logic for this case
}
updateSavedGeometry();
return;
}
else if (prop == &Type) {//why??
@@ -370,37 +386,26 @@ short DrawViewDimension::mustExecute() const
App::DocumentObjectExecReturn* DrawViewDimension::execute()
{
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
if (!keepUpdated()) {
// Base::Console().Message("DVD::execute() - %s\n", getNameInDocument());
if (!okToProceed()) {
return App::DocumentObject::StdReturn;
}
DrawViewPart* dvp = getViewPart();
if (!dvp)
return App::DocumentObject::StdReturn;
if (!has2DReferences() && !has3DReferences()) {
//no references, can't do anything
return App::DocumentObject::StdReturn;
}
if (!getViewPart()->hasGeometry()) {
//can't do anything until Source has geometry
return App::DocumentObject::StdReturn;
}
if (References3D.getValues().empty() && !checkReferences2D()) {
Base::Console().Warning("DVD::execute - %s has invalid 2D References\n",
getNameInDocument());
return App::DocumentObject::StdReturn;
}
//we have either or both valid References3D and References2D
ReferenceVector references = getEffectiveReferences();
resetLinear();
resetAngular();
resetArc();
m_referencesCorrect = compareSavedGeometry();
if (!m_referencesCorrect) {
m_referencesCorrect = fixExactMatch();
if (!m_referencesCorrect) {
handleNoExactMatch();
}
}
//we have either or both valid References3D and References2D
ReferenceVector references = getEffectiveReferences();
if (Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY")) {
if (getRefType() == oneEdge) {
m_linearPoints = getPointsOneEdge(references);
@@ -443,6 +448,35 @@ App::DocumentObjectExecReturn* DrawViewDimension::execute()
return DrawView::execute();
}
// true if we have enough information to execute, false otherwise
bool DrawViewDimension::okToProceed()
{
if (!keepUpdated()) {
return false;
}
DrawViewPart* dvp = getViewPart();
if (!dvp)
return false;
if (!has2DReferences() && !has3DReferences()) {
//no references, can't do anything
return App::DocumentObject::StdReturn;
}
if (!getViewPart()->hasGeometry()) {
//can't do anything until Source has geometry
return false;
}
if (References3D.getValues().empty() && !checkReferences2D()) {
Base::Console().Warning("DVD::execute - %s has invalid 2D References\n",
getNameInDocument());
return false;
}
return true;
}
////TODO: schema not report their multiValue status
bool DrawViewDimension::isMultiValueSchema() const { return m_formatter->isMultiValueSchema(); }
@@ -615,7 +649,6 @@ pointPair DrawViewDimension::getPointsOneEdge(ReferenceVector references)
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -650,7 +683,6 @@ pointPair DrawViewDimension::getPointsTwoEdges(ReferenceVector references)
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -690,7 +722,6 @@ pointPair DrawViewDimension::getPointsTwoVerts(ReferenceVector references)
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -731,7 +762,6 @@ pointPair DrawViewDimension::getPointsEdgeVert(ReferenceVector references)
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -762,7 +792,6 @@ arcPoints DrawViewDimension::getArcParameters(ReferenceVector references)
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -1089,7 +1118,6 @@ anglePoints DrawViewDimension::getAnglePointsTwoEdges(ReferenceVector references
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -1137,7 +1165,6 @@ anglePoints DrawViewDimension::getAnglePointsThreeVerts(ReferenceVector referenc
pts.move(getViewPart()->getOriginalCentroid());
pts.project(getViewPart());
pts.mapToPage(getViewPart());
pts.invertY();
return pts;
}
@@ -1206,6 +1233,21 @@ ReferenceVector DrawViewDimension::getReferences3d() const
return refs3d;
}
void DrawViewDimension::replaceReferenceSubElement2d(int iRef, std::string newSubelement)
{
// Base::Console().Message("DVD::replaceReferenceSubElement2d(%d, %s)\n", iRef, newSubelement.c_str());
ReferenceVector refs = getReferences2d();
refs.at(iRef).setSubName(newSubelement);
setReferences2d(refs);
}
void DrawViewDimension::replaceReferenceSubElement3d(int iRef, std::string newSubelement)
{
ReferenceVector refs = getReferences3d();
refs.at(iRef).setSubName(newSubelement);
setReferences3d(refs);
}
//what configuration of references do we have - Vertex-Vertex, Edge-Vertex, Edge, ...
int DrawViewDimension::getRefType() const
{
@@ -1313,6 +1355,275 @@ bool DrawViewDimension::checkReferences2D() const
return true;
}
void DrawViewDimension::updateSavedGeometry()
{
// Base::Console().Message("DVD::updateSavedGeometry() - %s - savedGeometry: %d\n",
// getNameInDocument(), SavedGeometry.getValues().size());
ReferenceVector references = getEffectiveReferences();
std::vector<TopoShape> newGeometry;
const std::vector<TopoShape> oldGeometry = SavedGeometry.getValues();
//need to clean up old geometry objects here?
for (auto& entry : references) {
if (entry.getSubName().empty()) {
// view only reference has no geometry.
continue;
}
newGeometry.push_back(entry.asTopoShape());
// Base::Console().Message("DVD::updateSavedGeometry - entry.isNull: %d\n", entry.asTopoShape().isNull());
}
if (newGeometry.empty()) {
//clear out the old SavedGeometry
SavedGeometry.clear();
} else {
SavedGeometry.setValues(newGeometry);
}
}
// routines related to detecting that references no longer point to the same geometry as
// when they were created.
// returns true if the saved geometry is the same as the current reference geometry
// returns false if the saved geometry is different from the the current reference geometry
bool DrawViewDimension::compareSavedGeometry()
{
// Base::Console().Message("DVD::compareSavedGeometry() - isRestoring: %d\n", isRestoring());
const std::vector<TopoShape> savedGeometry = SavedGeometry.getValues();
if (savedGeometry.empty()) {
// no saved geometry, so we have nothing to compare, so we don't know if there has been a change
return true;
}
ReferenceVector references = getEffectiveReferences();
std::vector<Part::TopoShape> referenceGeometry;
for (auto& entry : references) {
referenceGeometry.push_back(entry.asTopoShape());
}
if (savedGeometry.size() != referenceGeometry.size()) {
// Base::Console().Message("DVD::compareSavedGeometry - geometry sizes have changed\n");
return false;
}
int geometryCount = savedGeometry.size();
int iGeom = 0;
for ( ; iGeom < geometryCount; iGeom++) {
if (savedGeometry.at(iGeom).getTypeId() != referenceGeometry.at(iGeom).getTypeId()) {
// Base::Console().Message("DVD::compareSavedGeometry - saved geometry (%d) has different type\n", iGeom);
return false;
}
}
//saved and reference geometry have same count and types
for (iGeom = 0; iGeom < geometryCount; iGeom++) {
Part::TopoShape temp = savedGeometry.at(iGeom);
if (!m_matcher->compareGeometry(temp, referenceGeometry.at(iGeom)) ) {
// Base::Console().Message("DVD::compareSavedGeometry - saved geometry (%d) does not match current geometry\n", iGeom);
return false;
}
}
//free the reference geometry?
return true;
}
// deal with the situation where references do not point to the same geometry as
// when they were created.
bool DrawViewDimension::fixExactMatch()
{
// Base::Console().Message("DVD::fixExactMatch() - reference geometry has changed\n");
if (!Preferences::autoCorrectDimRefs()) {
return false;
}
ReferenceVector references = getEffectiveReferences();
std::vector< std::pair<int, std::string> > refsToFix2d;
std::vector< std::pair<int, std::string> > refsToFix3d;
bool success(true);
int referenceCount = references.size();
int iRef = 0;
for ( ; iRef < referenceCount; iRef++) {
std::string newReference("");
TopoDS_Shape geomShape = references.at(iRef).getGeometry();
if (references.at(iRef).is3d()) {
if (geomShape.ShapeType() == TopAbs_VERTEX) {
newReference = recoverChangedVertex3d(iRef);
} else {
newReference = recoverChangedEdge3d(iRef);
}
if (!newReference.empty()) {
std::pair<int, std::string> toFix(iRef, newReference);
refsToFix3d.push_back(toFix);
} else {
Base::Console().Warning("%s - no exact match for changed 3d reference: %d\n", getNameInDocument(), iRef);
success = false;
}
} else {
if (geomShape.ShapeType() == TopAbs_VERTEX) {
newReference = recoverChangedVertex2d(iRef);
} else {
newReference = recoverChangedEdge2d(iRef);
}
if (!newReference.empty()) {
std::pair<int, std::string> toFix(iRef, newReference);
refsToFix2d.push_back(toFix);
} else {
Base::Console().Warning("%s - no exact match for changed 2d reference: %d\n", getNameInDocument(), iRef);
success = false;
}
}
}
for (auto& fix : refsToFix2d) {
replaceReferenceSubElement2d(fix.first, fix.second);
}
for (auto& fix : refsToFix3d) {
replaceReferenceSubElement3d(fix.first, fix.second);
}
return success;
}
// deal with situation where the current geometry does not match the saved geometry,
// but we did not find an exact match in the geometry pile
void DrawViewDimension::handleNoExactMatch()
{
// Base::Console().Message("DVD::handleNoExactMatch()\n");
Base::Console().Message("%s - trying to match changed geometry - stage 2\n", getNameInDocument());
// this is where we insert the clever logic to determine that the changed geometry
// actually still represents the "front top left" edge.
updateSavedGeometry();
m_referencesCorrect = true;
}
//find an edge in the view that matches the reference entry's type and characteristics
std::string DrawViewDimension::recoverChangedEdge2d(int iReference)
{
// Base::Console().Message("DVD::recoverChangedEdge2d(ref: %d)\n", iReference);
double scale = getViewPart()->getScale();
Part::TopoShape savedGeometryItem = SavedGeometry.getValues().at(iReference);
std::vector<TechDraw::BaseGeomPtr> gEdges = getViewPart()->getEdgeGeometry();
int iEdge = 0;
for (auto& edge : gEdges) {
Part::TopoShape temp = edge->asTopoShape(scale);
if (savedGeometryItem.getTypeId() != temp.getTypeId()) {
// if the typeIds don't match, we can not compare the geometry
// Base::Console().Message("DVD::recoverChangedEdge2d - types do not match\n");
iEdge++;
continue;
}
bool isSame = m_matcher->compareGeometry(savedGeometryItem, temp);
// Base::Console().Message("DVD::recoverChangedEdge2d - iEdge: %d isSame: %d\n", iEdge, isSame);
if (isSame) {
return std::string("Edge") + std::to_string(iEdge);
}
iEdge++;
}
return std::string("");
}
std::string DrawViewDimension::recoverChangedVertex2d(int iReference)
{
// Base::Console().Message("DVD::recoverChangedVertex2d(%d)\n", iReference);
double scale = getViewPart()->getScale();
Part::TopoShape savedGeometryItem = SavedGeometry.getValues().at(iReference);
std::vector<TechDraw::VertexPtr> gVertexAll = getViewPart()->getVertexGeometry();
int iVertex = 0;
for (auto& vert : gVertexAll) {
Part::TopoShape temp = vert->asTopoShape(scale);
bool isSame = m_matcher->compareGeometry(savedGeometryItem, temp);
if (isSame) {
return std::string("Vertex") + std::to_string(iVertex);
}
iVertex++;
}
return std::string("");
}
std::string DrawViewDimension::recoverChangedEdge3d(int iReference)
{
// Base::Console().Message("DVD::recoverChangedEdge3d(%d)\n", iReference);
Part::TopoShape savedGeometryItem = SavedGeometry.getValues().at(iReference);
ReferenceVector references = getEffectiveReferences();
App::DocumentObject* searchObject = references.at(iReference).getObject();
Part::TopoShape shape = Part::Feature::getTopoShape(searchObject);
App::GeoFeature* geoFeat = dynamic_cast<App::GeoFeature*>(searchObject);
//does a feature in a body get the body's globalPlacement??
if (geoFeat) {
shape.setPlacement(geoFeat->globalPlacement());
}
//TODO: these TopoShapes will have to be released when we are finished with them
std::vector<TopoShape> edgesAll = getEdges(shape);
int iEdge = 1; //note that edge numbering starts at 1!
for (auto& edge : edgesAll) {
bool isSame = m_matcher->compareGeometry(savedGeometryItem, edge);
if (isSame) {
return std::string("Edge") + std::to_string(iEdge);
}
iEdge++;
}
return std::string("");
}
// based on Part::TopoShapePyImp::getShapes. Produces a vector of unique edges within the shape
std::vector<TopoShape> DrawViewDimension::getEdges(const TopoShape& inShape)
{
std::vector<TopoShape> ret;
TopTools_IndexedMapOfShape M;
TopExp_Explorer Ex(inShape.getShape(), TopAbs_EDGE);
while (Ex.More()) {
M.Add(Ex.Current());
Ex.Next();
}
for (Standard_Integer k = 1; k <= M.Extent(); k++) {
const TopoDS_Shape& shape = M(k);
ret.push_back(TopoShape(shape));
}
return ret;
}
// as recoverChangedVertex2d, but 3d references do not need to be unscaled
std::string DrawViewDimension::recoverChangedVertex3d(int iReference)
{
// Base::Console().Message("DVD::recoverChangedVertex3d(%d)\n", iReference);
Part::TopoShape savedGeometryItem = SavedGeometry.getValues().at(iReference);
ReferenceVector references = getEffectiveReferences();
App::DocumentObject* searchObject = references.at(iReference).getObject();
Part::TopoShape shape = Part::Feature::getTopoShape(searchObject);
App::GeoFeature* geoFeat = dynamic_cast<App::GeoFeature*>(searchObject);
if (geoFeat) {
shape.setPlacement(geoFeat->globalPlacement());
}
//TODO: these TopoShapes will have to be released when we are finished with them
std::vector<TopoShape> vertsAll = getVertexes(shape);
int iVert = 1; //note that vertex numbering starts at 1!
for (auto& vert : vertsAll) {
bool isSame = m_matcher->compareGeometry(savedGeometryItem, vert);
if (isSame) {
return std::string("Vertex") + std::to_string(iVert);
}
iVert++;
}
return std::string("");
}
// based on Part::TopoShapePyImp::getShapes
std::vector<TopoShape> DrawViewDimension::getVertexes(const TopoShape& inShape)
{
std::vector<TopoShape> ret;
TopTools_IndexedMapOfShape M;
TopExp_Explorer Ex(inShape.getShape(), TopAbs_VERTEX);
while (Ex.More()) {
M.Add(Ex.Current());
Ex.Next();
}
for (Standard_Integer k = 1; k <= M.Extent(); k++) {
const TopoDS_Shape& shape = M(k);
ret.push_back(TopoShape(shape));
}
return ret;
}
pointPair DrawViewDimension::closestPoints(TopoDS_Shape s1, TopoDS_Shape s2) const
{
pointPair result;
@@ -1334,6 +1645,7 @@ pointPair DrawViewDimension::closestPoints(TopoDS_Shape s1, TopoDS_Shape s2) con
//set the reference property from a reference vector
void DrawViewDimension::setReferences2d(ReferenceVector refs)
{
// Base::Console().Message("DVD::setReferences2d(%d)\n", refs.size());
std::vector<App::DocumentObject*> objects;
std::vector<std::string> subNames;
if (objects.size() != subNames.size()) {
@@ -1351,6 +1663,11 @@ void DrawViewDimension::setReferences2d(ReferenceVector refs)
//set the reference property from a reference vector
void DrawViewDimension::setReferences3d(ReferenceVector refs)
{
if (refs.empty() && !References3D.getValues().empty()) {
//clear the property of any old links
References3D.setValue(nullptr, nullptr);
return;
}
std::vector<App::DocumentObject*> objects;
std::vector<std::string> subNames;
if (objects.size() != subNames.size()) {

View File

@@ -27,6 +27,8 @@
#include <App/DocumentObject.h>
#include <Base/UnitsApi.h>
#include <Mod/Part/App/PropertyTopoShapeList.h>
#include <Mod/TechDraw/TechDrawGlobal.h>
#include "DimensionGeometry.h"
@@ -35,7 +37,6 @@
#include "DrawView.h"
#include "DrawViewPart.h"
class TopoDS_Shape;
namespace Measure {
@@ -45,6 +46,7 @@ namespace TechDraw
{
class DrawViewPart;
class DimensionFormatter;
class GeometryMatcher;
class TechDrawExport DrawViewDimension : public TechDraw::DrawView
{
@@ -88,6 +90,8 @@ enum DimensionType {
App::PropertyAngle LineAngle;
App::PropertyAngle ExtensionAngle;
Part::PropertyTopoShapeList SavedGeometry;
enum RefType{
invalidRef,
oneEdge,
@@ -157,6 +161,7 @@ enum DimensionType {
bool useDecimals() const;
bool isExtentDim() const;
virtual ReferenceVector getEffectiveReferences() const;
bool goodReferenceGeometry() const { return m_referencesCorrect; }
protected:
void handleChangedPropertyType(Base::XMLReader &, const char * , App::Property * ) override;
@@ -177,7 +182,6 @@ protected:
virtual anglePoints getAnglePointsTwoEdges(ReferenceVector references);
virtual anglePoints getAnglePointsThreeVerts(ReferenceVector references);
protected:
Measure::Measurement *measurement;
double dist2Segs(Base::Vector3d s1,
Base::Vector3d e1,
@@ -190,6 +194,21 @@ protected:
void resetAngular();
void resetArc();
bool okToProceed();
void updateSavedGeometry();
bool compareSavedGeometry();
bool fixExactMatch();
void handleNoExactMatch();
std::string recoverChangedEdge2d(int iReference);
std::string recoverChangedEdge3d(int iReference);
std::string recoverChangedVertex2d(int iReference);
std::string recoverChangedVertex3d(int iReference);
void replaceReferenceSubElement2d(int iRef, std::string newSubelement);
void replaceReferenceSubElement3d(int iRef, std::string newSubelement);
std::vector<Part::TopoShape> getEdges(const Part::TopoShape& inShape);
std::vector<Part::TopoShape> getVertexes(const Part::TopoShape& inShape);
private:
static const char* TypeEnums[];
static const char* MeasureTypeEnums[];
@@ -203,6 +222,9 @@ private:
friend class DimensionFormatter;
DimensionFormatter* m_formatter;
GeometryMatcher* m_matcher;
bool m_referencesCorrect;
};
} //namespace TechDraw

View File

@@ -1336,9 +1336,8 @@ Base::Vector3d DrawViewPart::getXDirection() const
Base::Vector3d dir = Direction.getValue(); //make a sensible default
Base::Vector3d org(0.0, 0.0, 0.0);
result = getLegacyX(org, dir);
}
else {
result = propVal;//normal case. XDirection is set.
} else {
result = propVal; //normal case. XDirection is set.
}
}
else { //no Property. can this happen?

View File

@@ -74,13 +74,18 @@
#include <Base/Reader.h>
#include <Base/Writer.h>
#include <Mod/Part/App/Geometry.h>
#include <Mod/Part/App/TopoShape.h>
#include "Geometry.h"
#include "GeometryObject.h"
#include "DrawUtil.h"
using namespace TechDraw;
using namespace Part;
using namespace std;
using DU = DrawUtil;
#if OCC_VERSION_HEX >= 0x070600
using BRepAdaptor_HCurve = BRepAdaptor_Curve;
@@ -704,6 +709,14 @@ void BaseGeom::intersectionCC(TechDraw::BaseGeomPtr geom1,
}
}
TopoShape BaseGeom::asTopoShape(double scale)
{
// Base::Console().Message("BG::asTopoShape(%.3f) - dump: %s\n", scale, dump().c_str());
TopoDS_Shape unscaledShape = TechDraw::scaleShape(getOCCEdge(), 1.0 / scale);
TopoDS_Edge unscaledEdge = TopoDS::Edge(unscaledShape);
return unscaledEdge;
}
Ellipse::Ellipse(const TopoDS_Edge &e)
{
geomType = ELLIPSE;
@@ -1496,6 +1509,14 @@ void Vertex::dump(const char* title)
cosmeticTag.c_str());
}
TopoShape Vertex::asTopoShape(double scale)
{
Base::Vector3d point = DU::toVector3d(BRep_Tool::Pnt(getOCCVertex()));
point = point / scale;
BRepBuilderAPI_MakeVertex mkVert(DU::togp_Pnt(point));
return TopoShape(mkVert.Vertex());
}
/*static*/
BaseGeomPtrVector GeometryUtils::chainGeoms(BaseGeomPtrVector geoms)

View File

@@ -36,6 +36,9 @@
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
namespace Part {
class TopoShape;
}
namespace TechDraw {
@@ -142,6 +145,7 @@ class TechDrawExport BaseGeom : public std::enable_shared_from_this<BaseGeom>
void sourceIndex(int si) { m_sourceIndex = si; }
std::string getCosmeticTag() { return cosmeticTag; }
void setCosmeticTag(std::string t) { cosmeticTag = t; }
Part::TopoShape asTopoShape(double scale);
protected:
void createNewTag();
@@ -377,6 +381,8 @@ class TechDrawExport Vertex
bool isReference() { return m_reference; }
void isReference(bool state) { m_reference = state; }
Part::TopoShape asTopoShape(double scale);
protected:
//Uniqueness
void createNewTag();

View File

@@ -0,0 +1,262 @@
/***************************************************************************
* Copyright (c) 2023 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
// a class to handle changes to dimension reference geometry
// detects changes in reference geometry (2d & 3d) that would invalidate a dimension
// identifies replacement view/model geometry
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include <BRepAdaptor_Curve.hxx>
#include <BRepLProp_CLProps.hxx>
#include <BRep_Tool.hxx>
#include <gp_Circ.hxx>
#include <gp_Elips.hxx>
#include <TopExp.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Mod/Part/App/TopoShape.h>
#include "GeometryMatcher.h"
#include "DrawUtil.h"
using namespace TechDraw;
using DU = DrawUtil;
// a set of routines for comparing geometry for equality.
bool GeometryMatcher::compareGeometry(Part::TopoShape shape1, Part::TopoShape shape2)
{
// Base::Console().Message("GM::compareGeometry()\n");
if (shape1.isNull() || shape2.isNull()) {
Base::Console().Message("GM::compareGeometry - one or more shapes are null\n");
}
TopoDS_Shape geom1 = shape1.getShape();
TopoDS_Shape geom2 = shape2.getShape();
if (geom1.ShapeType() == TopAbs_VERTEX) {
return comparePoints(geom1, geom2);
}
if (geom1.ShapeType() == TopAbs_EDGE) {
return compareEdges(geom1, geom2);
}
return false;
}
bool GeometryMatcher::comparePoints(TopoDS_Shape shape1, TopoDS_Shape shape2)
{
// Base::Console().Message("GM::comparePoints()\n");
if (shape1.ShapeType() != TopAbs_VERTEX ||
shape2.ShapeType() != TopAbs_VERTEX) {
// can not compare these shapes
return false;
}
auto vert1 = TopoDS::Vertex(shape1);
Base::Vector3d point1 = DU::toVector3d(BRep_Tool::Pnt(vert1));
auto vert2 = TopoDS::Vertex(shape2);
Base::Vector3d point2 = DU::toVector3d(BRep_Tool::Pnt(vert2));
if (point1.IsEqual(point2, EWTOLERANCE)) {
return true;
}
return false;
}
bool GeometryMatcher::compareEdges(TopoDS_Shape shape1, TopoDS_Shape shape2)
{
// Base::Console().Message("GM::compareEdges()\n");
if (shape1.ShapeType() != TopAbs_EDGE ||
shape2.ShapeType() != TopAbs_EDGE) {
// can not compare these shapes
// Base::Console().Message("GM::compareEdges - shape is not an edge\n");
return false;
}
TopoDS_Edge edge1 = TopoDS::Edge(shape1);
TopoDS_Edge edge2 = TopoDS::Edge(shape2);
BRepAdaptor_Curve adapt1(edge1);
BRepAdaptor_Curve adapt2(edge2);
if (adapt1.GetType() == GeomAbs_Line &&
adapt2.GetType() == GeomAbs_Line) {
return compareLines(edge1, edge2);
}
if (adapt1.GetType() == GeomAbs_Circle &&
adapt2.GetType() == GeomAbs_Circle) {
if (adapt1.IsClosed() && adapt2.IsClosed()) {
return compareCircles(edge1, edge2);
} else {
return compareCircleArcs(edge1, edge2);
}
}
if (adapt1.GetType() == GeomAbs_Ellipse &&
adapt2.GetType() == GeomAbs_Ellipse) {
if (adapt1.IsClosed() && adapt2.IsClosed()) {
return compareEllipses(edge1, edge2);
} else {
return compareEllipseArcs(edge1, edge2);
}
}
if (adapt1.GetType() == GeomAbs_BSplineCurve &&
adapt2.GetType() == GeomAbs_BSplineCurve) {
return compareBSplines(edge1, edge2);
}
// if we reach this point, we have dissimilar geometry types
return compareDifferent(edge1, edge2);
}
bool GeometryMatcher::compareLines(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
// Base::Console().Message("GM::compareLines()\n");
auto start1 = DU::toVector3d(BRep_Tool::Pnt(TopExp::FirstVertex(edge1)));
auto end1 = DU::toVector3d(BRep_Tool::Pnt(TopExp::LastVertex(edge1)));
auto start2 = DU::toVector3d(BRep_Tool::Pnt(TopExp::FirstVertex(edge2)));
auto end2 = DU::toVector3d(BRep_Tool::Pnt(TopExp::LastVertex(edge2)));
if (start1.IsEqual(start2, EWTOLERANCE) &&
end1.IsEqual(end2, EWTOLERANCE)) {
//exact match
return true;
}
return false;
}
bool GeometryMatcher::compareCircles(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
// Base::Console().Message("GM::compareCircles()\n");
BRepAdaptor_Curve adapt1(edge1);
BRepAdaptor_Curve adapt2(edge2);
gp_Circ circle1 = adapt1.Circle();
gp_Circ circle2 = adapt2.Circle();
double radius1 = circle1.Radius();
double radius2 = circle2.Radius();
auto center1 = DU::toVector3d(circle1.Location());
auto center2 = DU::toVector3d(circle2.Location());
if (DU::fpCompare(radius1, radius2, EWTOLERANCE) &&
center1.IsEqual(center2, EWTOLERANCE)) {
//exact match
return true;
}
return false;
}
bool GeometryMatcher::compareEllipses(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
BRepAdaptor_Curve adapt1(edge1);
BRepAdaptor_Curve adapt2(edge2);
gp_Elips ellipse1 = adapt1.Ellipse();
gp_Elips ellipse2 = adapt2.Ellipse();
double major1 = ellipse1.MajorRadius();
double minor1 = ellipse1.MinorRadius();
double major2 = ellipse2.MajorRadius();
double minor2 = ellipse2.MinorRadius();
auto center1 = DU::toVector3d(ellipse1.Location());
auto center2 = DU::toVector3d(ellipse2.Location());
if (DU::fpCompare(major1, major2, EWTOLERANCE) &&
DU::fpCompare(minor1, minor2, EWTOLERANCE) &&
center1.IsEqual(center2, EWTOLERANCE)) {
// exact match
return true;
}
return false;
}
// for our purposes, only circles masquerading as bsplines are of interest
bool GeometryMatcher::compareBSplines(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
BRepAdaptor_Curve adapt1(edge1);
BRepAdaptor_Curve adapt2(edge2);
bool isArc1(false);
bool isArc2(false);
TopoDS_Edge circleEdge1;
TopoDS_Edge circleEdge2;
try {
circleEdge1 = GeometryUtils::asCircle(edge1, isArc1);
circleEdge2 = GeometryUtils::asCircle(edge2, isArc1);
}
catch (Base::RuntimeError& e) {
Base::Console().Error("GeometryMatcher failed to make circles from splines\n");
return false;
}
if (!isArc1 && !isArc2) {
// full circles
return compareCircles(circleEdge1, circleEdge2);
}
if (isArc1 && isArc2) {
// circular arcs
return compareCircleArcs(circleEdge1, circleEdge2);
}
return false;
}
// this is a weak comparison. we should also check center & radius?
bool GeometryMatcher::compareCircleArcs(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
return compareEndPoints(edge1, edge2);
}
bool GeometryMatcher::compareEllipseArcs(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
return compareEndPoints(edge1, edge2);
}
// this is where we would try to match a bspline against a line or a circle.
// not sure how successful this would be. For now, we just say it doesn't match
bool GeometryMatcher::compareDifferent(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
BRepAdaptor_Curve adapt1(edge1);
BRepAdaptor_Curve adapt2(edge2);
return false;
}
bool GeometryMatcher::compareEndPoints(TopoDS_Edge edge1, TopoDS_Edge edge2)
{
BRepAdaptor_Curve adapt1(edge1);
BRepAdaptor_Curve adapt2(edge2);
double pFirst1 = adapt1.FirstParameter();
double pLast1 = adapt1.LastParameter();
BRepLProp_CLProps props1(adapt1, pFirst1, 0, Precision::Confusion());
auto begin1 = DU::toVector3d(props1.Value());
props1.SetParameter(pLast1);
auto end1 = DU::toVector3d(props1.Value());
double pFirst2 = adapt2.FirstParameter();
double pLast2 = adapt2.LastParameter();
BRepLProp_CLProps props2(adapt2, pFirst2, 0, Precision::Confusion());
auto begin2 = DU::toVector3d(props2.Value());
props2.SetParameter(pLast2);
auto end2 = DU::toVector3d(props2.Value());
if (begin1.IsEqual(begin2, EWTOLERANCE) &&
end1.IsEqual(end2, EWTOLERANCE)) {
//exact match
return true;
}
return false;
}

View File

@@ -0,0 +1,64 @@
/***************************************************************************
* Copyright (c) 2023 WandererFan <wandererfan@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
// a class to handle changes to dimension reference geometry
#ifndef GEOMETRYMATCHER_H
#define GEOMETRYMATCHER_H
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <DrawViewDimension.h>
namespace Part
{
class TopoShape;
}
namespace TechDraw {
class TechDrawExport GeometryMatcher {
public:
GeometryMatcher() {}
GeometryMatcher(DrawViewDimension* dim) { m_dimension = dim; }
~GeometryMatcher() = default;
bool compareGeometry(Part::TopoShape geom1, Part::TopoShape geom2);
bool comparePoints(TopoDS_Shape shape1, TopoDS_Shape shape2);
bool compareEdges(TopoDS_Shape shape1, TopoDS_Shape shape2);
bool compareLines(TopoDS_Edge edge1, TopoDS_Edge edge2);
bool compareCircles(TopoDS_Edge edge1, TopoDS_Edge edge2);
bool compareEllipses(TopoDS_Edge edge1, TopoDS_Edge edge2);
bool compareBSplines(TopoDS_Edge edge1, TopoDS_Edge edge2);
bool compareDifferent(TopoDS_Edge edge1, TopoDS_Edge edge2);
bool compareCircleArcs(TopoDS_Edge edge1, TopoDS_Edge edge2);
bool compareEllipseArcs(TopoDS_Edge edge1, TopoDS_Edge edge2);
private:
bool compareEndPoints(TopoDS_Edge edge1, TopoDS_Edge edge2);
DrawViewDimension* m_dimension;
};
} //end namespace TechDraw
#endif

View File

@@ -1044,11 +1044,9 @@ void CmdTechDrawBalloon::activated(int iMsg)
{
Q_UNUSED(iMsg);
bool result = _checkSelectionBalloon(this, 1);
if (!result)
if (!result) {
return;
// result = _checkDrawViewPartBalloon(this);
// if (!result)
// return;
}
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
@@ -1085,7 +1083,8 @@ bool CmdTechDrawBalloon::isActive()
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this, false);
return (havePage && haveView);
bool taskInProgress = Gui::Control().activeDialog();
return (havePage && haveView && !taskInProgress);
}
//===========================================================================

View File

@@ -536,6 +536,7 @@ void QGIView::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q
QRectF QGIView::customChildrenBoundingRect() const
{
QList<QGraphicsItem*> children = childItems();
// exceptions not to be included in determining the frame rectangle
int dimItemType = QGraphicsItem::UserType + 106; // TODO: Get magic number from include by name
int borderItemType = QGraphicsItem::UserType + 136; // TODO: Magic number warning
int labelItemType = QGraphicsItem::UserType + 135; // TODO: Magic number warning
@@ -563,7 +564,6 @@ QRectF QGIView::customChildrenBoundingRect() const
(child->type() != centerMarkItemType)) {
QRectF childRect = mapFromItem(child, child->boundingRect()).boundingRect();
result = result.united(childRect);
//result = result.united((*it)->boundingRect());
}
}
return result;

View File

@@ -52,6 +52,7 @@
#include "QGIArrow.h"
#include "QGIDimLines.h"
#include "QGIVertex.h"
#include "QGCustomSvg.h"
#include "ViewProviderDimension.h"
#include "ZVALUE.h"
@@ -512,6 +513,12 @@ QGIViewDimension::QGIViewDimension() : dvDimension(nullptr), hasHover(false), m_
setZValue(ZVALUE::DIMENSION);//note: this won't paint dimensions over another View if it stacks
//above this Dimension's parent view. need Layers?
hideFrame();
m_refFlag = new QGCustomSvg();
m_refFlag->setParentItem(this);
m_refFlag->load(QString::fromUtf8(":/icons/TechDraw_RefError.svg"));
m_refFlag->setZValue(ZVALUE::LOCK);
m_refFlag->hide();
}
QVariant QGIViewDimension::itemChange(GraphicsItemChange change, const QVariant& value)
@@ -637,6 +644,14 @@ void QGIViewDimension::updateView(bool update)
updateDim();
}
if (dim->goodReferenceGeometry()) {
m_refFlag->hide();
} else {
// m_refFlag->setPos(datumLabel->pos());
m_refFlag->centerAt(datumLabel->pos() + datumLabel->boundingRect().center());
m_refFlag->show();
}
draw();
}

View File

@@ -53,6 +53,7 @@ class QGCustomText;
class QGIArrow;
class QGIDimLines;
class QGIViewDimension;
class QGCustomSvg;
class ViewProviderDimension;
class QGIDatumLabel : public QGraphicsObject
@@ -134,6 +135,7 @@ private:
QGCustomText* m_tolTextOver;
QGCustomText* m_tolTextUnder;
QGCustomText* m_unitText;
QGCustomText* m_referenceFlag;
QColor m_colNormal;
bool m_ctrl;
@@ -303,6 +305,9 @@ private:
QGIArrow* aHead1;
QGIArrow* aHead2;
double m_lineWidth;
QGCustomSvg* m_refFlag;
};
} // namespace MDIViewPageGui