[TD]fix dimension autocorrect
- autocorrect was not handling scaled and rotated reference geometry properly.
This commit is contained in:
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#include <QLocale>
|
||||
@@ -300,7 +299,7 @@ void DrawViewDimension::onChanged(const App::Property* prop)
|
||||
}
|
||||
else if (prop == &Type) {
|
||||
FormatSpec.setValue(getDefaultFormatSpec().c_str());
|
||||
DimensionType type = static_cast<DimensionType>(Type.getValue());
|
||||
auto type = static_cast<DimensionType>(Type.getValue());
|
||||
if (type == DimensionType::Angle || type == DimensionType::Angle3Pt) {
|
||||
OverTolerance.setUnit(Base::Unit::Angle);
|
||||
UnderTolerance.setUnit(Base::Unit::Angle);
|
||||
@@ -391,7 +390,7 @@ void DrawViewDimension::onDocumentRestored()
|
||||
setAll3DMeasurement();
|
||||
}
|
||||
|
||||
DimensionType type = static_cast<DimensionType>(Type.getValue());
|
||||
auto type = static_cast<DimensionType>(Type.getValue());
|
||||
if (type == DimensionType::Angle || type == DimensionType::Angle3Pt) {
|
||||
OverTolerance.setUnit(Base::Unit::Angle);
|
||||
UnderTolerance.setUnit(Base::Unit::Angle);
|
||||
@@ -403,14 +402,14 @@ void DrawViewDimension::handleChangedPropertyType(Base::XMLReader& reader,
|
||||
App::Property* prop)
|
||||
{
|
||||
if (prop == &OverTolerance && strcmp(TypeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat v;
|
||||
v.Restore(reader);
|
||||
OverTolerance.setValue(v.getValue());
|
||||
App::PropertyFloat value;
|
||||
value.Restore(reader);
|
||||
OverTolerance.setValue(value.getValue());
|
||||
}
|
||||
else if (prop == &UnderTolerance && strcmp(TypeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat v;
|
||||
v.Restore(reader);
|
||||
UnderTolerance.setValue(v.getValue());
|
||||
App::PropertyFloat value;
|
||||
value.Restore(reader);
|
||||
UnderTolerance.setValue(value.getValue());
|
||||
}
|
||||
else {
|
||||
TechDraw::DrawView::handleChangedPropertyType(reader, TypeName, prop);
|
||||
@@ -436,7 +435,7 @@ short DrawViewDimension::mustExecute() const
|
||||
{
|
||||
if (!isRestoring()) {
|
||||
if (References2D.isTouched() || References3D.isTouched() || Type.isTouched()) {
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,36 +449,19 @@ App::DocumentObjectExecReturn* DrawViewDimension::execute()
|
||||
return new App::DocumentObjectExecReturn("Dimension could not execute");
|
||||
}
|
||||
|
||||
m_referencesCorrect = true;
|
||||
if (Preferences::autoCorrectDimRefs()) {
|
||||
m_referencesCorrect = autocorrectReferences();
|
||||
}
|
||||
if (!m_referencesCorrect) {
|
||||
new App::DocumentObjectExecReturn("Autocorrect failed to fix broken references", this);
|
||||
}
|
||||
|
||||
// references are good, we can proceed
|
||||
resetLinear();
|
||||
resetAngular();
|
||||
resetArc();
|
||||
|
||||
// check if geometry pointed to by references matches the saved version. If
|
||||
// everything matches, we don't need to correct anything.
|
||||
std::vector<bool> referenceState;
|
||||
bool refsAreValid = m_corrector->referencesHaveValidGeometry(referenceState);
|
||||
if (!refsAreValid) {
|
||||
m_corrector->set3dObjectCache(m_3dObjectCache);
|
||||
ReferenceVector repairedRefs;
|
||||
refsAreValid = m_corrector->autocorrectReferences(referenceState, repairedRefs);
|
||||
if (!refsAreValid) {
|
||||
// references are broken and we can not fix them
|
||||
Base::Console().Warning("Autocorrect failed to fix references for %s\n",
|
||||
getNameInDocument());
|
||||
m_referencesCorrect = false;
|
||||
return new App::DocumentObjectExecReturn("Autocorrect failed to fix broken references",
|
||||
this);
|
||||
}
|
||||
if (repairedRefs.front().is3d()) {
|
||||
setReferences3d(repairedRefs);
|
||||
}
|
||||
else {
|
||||
setReferences2d(repairedRefs);
|
||||
}
|
||||
}
|
||||
// references are good, we can proceed
|
||||
m_referencesCorrect = true;
|
||||
|
||||
// we have either or both valid References3D and References2D
|
||||
ReferenceVector references = getEffectiveReferences();
|
||||
|
||||
@@ -498,11 +480,8 @@ App::DocumentObjectExecReturn* DrawViewDimension::execute()
|
||||
}
|
||||
m_hasGeometry = true;
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
m_arcPoints = getArcParameters(references);
|
||||
m_hasGeometry = true;
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
else if (Type.isValue("Radius") ||
|
||||
Type.isValue("Diameter") ) {
|
||||
m_arcPoints = getArcParameters(references);
|
||||
m_hasGeometry = true;
|
||||
}
|
||||
@@ -533,17 +512,21 @@ bool DrawViewDimension::okToProceed()
|
||||
}
|
||||
DrawViewPart* dvp = getViewPart();
|
||||
if (!dvp) {
|
||||
// TODO: translate these messages
|
||||
// this case is probably temporary during restore
|
||||
// Base::Console().Message("DVD::okToProceed - no view for dimension\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!has2DReferences() && !has3DReferences()) {
|
||||
if (!(has2DReferences() || has3DReferences())) {
|
||||
// no references, can't do anything
|
||||
Base::Console().Warning("Dimension object has no valid references\n");
|
||||
Base::Console().Warning("DVD::okToProceed - Dimension object has no valid references\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getViewPart()->hasGeometry()) {
|
||||
// can't do anything until Source has geometry
|
||||
Base::Console().Warning("DVD::okToProceed - Dimension object has no geometry\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -556,6 +539,34 @@ bool DrawViewDimension::okToProceed()
|
||||
return validateReferenceForm();
|
||||
}
|
||||
|
||||
//! check if geometry pointed to by references matches the saved version. If
|
||||
//! everything matches, we don't need to correct anything.
|
||||
bool DrawViewDimension::autocorrectReferences()
|
||||
{
|
||||
// Base::Console().Message("DVD::autocorrectReferences()\n");
|
||||
std::vector<bool> referenceState;
|
||||
bool refsAreValid = m_corrector->referencesHaveValidGeometry(referenceState);
|
||||
if (!refsAreValid) {
|
||||
m_corrector->set3dObjectCache(m_3dObjectCache);
|
||||
ReferenceVector repairedRefs;
|
||||
refsAreValid = m_corrector->autocorrectReferences(referenceState, repairedRefs);
|
||||
if (!refsAreValid) {
|
||||
// references are broken and we can not fix them
|
||||
Base::Console().Warning("Autocorrect failed to fix references for %s\n",
|
||||
getNameInDocument());
|
||||
return false;
|
||||
|
||||
}
|
||||
if (repairedRefs.front().is3d()) {
|
||||
setReferences3d(repairedRefs);
|
||||
}
|
||||
else {
|
||||
setReferences2d(repairedRefs);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DrawViewDimension::isMultiValueSchema() const
|
||||
{
|
||||
return m_formatter->isMultiValueSchema();
|
||||
@@ -596,7 +607,7 @@ std::string DrawViewDimension::getFormattedDimensionValue(int partial)
|
||||
return m_formatter->getFormattedDimensionValue(partial);
|
||||
}
|
||||
|
||||
QStringList DrawViewDimension::getPrefixSuffixSpec(QString fSpec)
|
||||
QStringList DrawViewDimension::getPrefixSuffixSpec(const QString &fSpec)
|
||||
{
|
||||
return m_formatter->getPrefixSuffixSpec(fSpec);
|
||||
}
|
||||
@@ -605,6 +616,7 @@ QStringList DrawViewDimension::getPrefixSuffixSpec(QString fSpec)
|
||||
double DrawViewDimension::getDimValue()
|
||||
{
|
||||
// Base::Console().Message("DVD::getDimValue()\n");
|
||||
constexpr double CircleDegrees{360.0};
|
||||
double result = 0.0;
|
||||
if (!has2DReferences() && !has3DReferences()) {
|
||||
// nothing to measure
|
||||
@@ -625,21 +637,7 @@ double DrawViewDimension::getDimValue()
|
||||
getNameInDocument());
|
||||
return result;
|
||||
}
|
||||
if (Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY")) {
|
||||
result = measurement->length();
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
result = measurement->radius();
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
result = 2.0 * measurement->radius();
|
||||
}
|
||||
else if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) {
|
||||
result = measurement->angle();
|
||||
}
|
||||
else { // tarfu
|
||||
throw Base::ValueError("getDimValue() - Unknown Dimension Type (3)");
|
||||
}
|
||||
result = getTrueDimValue();
|
||||
}
|
||||
else {
|
||||
// Projected Values
|
||||
@@ -648,59 +646,13 @@ double DrawViewDimension::getDimValue()
|
||||
getNameInDocument());
|
||||
return result;
|
||||
}
|
||||
if (Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY")) {
|
||||
pointPair pts = getLinearPoints();
|
||||
auto dbv = dynamic_cast<DrawBrokenView*>(getViewPart());
|
||||
if (dbv) {
|
||||
// raw pts from view are inverted Y, so we need to un-invert them before mapping
|
||||
// raw pts are scaled, so we need to unscale them for mapPoint2dFromView
|
||||
// then rescale them for the distance calculation below
|
||||
// centers are right side up
|
||||
// if both points are on the expanded side of the last (rightmost/upmost) break
|
||||
// then we should not move the points.
|
||||
//
|
||||
pts.invertY();
|
||||
pts.scale(1.0 / getViewPart()->getScale());
|
||||
pts.first(dbv->mapPoint2dFromView(pts.first()));
|
||||
pts.second(dbv->mapPoint2dFromView(pts.second()));
|
||||
pts.invertY();
|
||||
pts.scale(getViewPart()->getScale());
|
||||
}
|
||||
Base::Vector3d dimVec = pts.first() - pts.second();
|
||||
if (Type.isValue("Distance")) {
|
||||
result = dimVec.Length() / getViewPart()->getScale();
|
||||
}
|
||||
else if (Type.isValue("DistanceX")) {
|
||||
result = fabs(dimVec.x) / getViewPart()->getScale();
|
||||
}
|
||||
else {
|
||||
result = fabs(dimVec.y) / getViewPart()->getScale();
|
||||
}
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
arcPoints pts = m_arcPoints;
|
||||
result =
|
||||
pts.radius / getViewPart()->getScale(); // Projected BaseGeom is scaled for drawing
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
arcPoints pts = m_arcPoints;
|
||||
result = (pts.radius * 2.0)
|
||||
/ getViewPart()->getScale(); // Projected BaseGeom is scaled for drawing
|
||||
}
|
||||
else if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) { // same as case "Angle"?
|
||||
anglePoints pts = m_anglePoints;
|
||||
Base::Vector3d vertex = pts.vertex();
|
||||
Base::Vector3d leg0 = pts.first() - vertex;
|
||||
Base::Vector3d leg1 = pts.second() - vertex;
|
||||
double legAngle = leg0.GetAngle(leg1) * 180.0 / M_PI;
|
||||
result = legAngle;
|
||||
}
|
||||
result = getProjectedDimValue();
|
||||
}
|
||||
|
||||
result = fabs(result);
|
||||
if (Inverted.getValue()) {
|
||||
if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) {
|
||||
result = 360 - result;
|
||||
result = CircleDegrees - result;
|
||||
}
|
||||
else {
|
||||
result = -result;
|
||||
@@ -709,6 +661,88 @@ double DrawViewDimension::getDimValue()
|
||||
return result;
|
||||
}
|
||||
|
||||
//! retrieve the dimension value for "true" dimensions. The returned value is in internal units (mm).
|
||||
double DrawViewDimension::getTrueDimValue() const
|
||||
{
|
||||
// Base::Console().Message("DVD::getTrueDimValue()\n");
|
||||
double result = 0.0;
|
||||
|
||||
if (Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY")) {
|
||||
result = measurement->length();
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
result = measurement->radius();
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
result = 2.0 * measurement->radius();
|
||||
}
|
||||
else if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) {
|
||||
result = measurement->angle();
|
||||
}
|
||||
else { // tarfu
|
||||
throw Base::ValueError("getDimValue() - Unknown Dimension Type (3)");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//! retrieve the dimension value for "projected" (2d) dimensions. The returned value is in internal units (mm).
|
||||
double DrawViewDimension::getProjectedDimValue() const
|
||||
{
|
||||
// Base::Console().Message("DVD::getProjectedDimValue()\n");
|
||||
double result = 0.0;
|
||||
|
||||
if (Type.isValue("Distance") || Type.isValue("DistanceX") || Type.isValue("DistanceY")) {
|
||||
pointPair pts = getLinearPoints();
|
||||
auto dbv = dynamic_cast<DrawBrokenView*>(getViewPart());
|
||||
if (dbv) {
|
||||
// raw pts from view are inverted Y, so we need to un-invert them before mapping
|
||||
// raw pts are scaled, so we need to unscale them for mapPoint2dFromView
|
||||
// then rescale them for the distance calculation below
|
||||
// centers are right side up
|
||||
// if both points are on the expanded side of the last (rightmost/upmost) break
|
||||
// then we should not move the points.
|
||||
//
|
||||
pts.invertY();
|
||||
pts.scale(1.0 / getViewPart()->getScale());
|
||||
pts.first(dbv->mapPoint2dFromView(pts.first()));
|
||||
pts.second(dbv->mapPoint2dFromView(pts.second()));
|
||||
pts.invertY();
|
||||
pts.scale(getViewPart()->getScale());
|
||||
}
|
||||
Base::Vector3d dimVec = pts.first() - pts.second();
|
||||
if (Type.isValue("Distance")) {
|
||||
result = dimVec.Length() / getViewPart()->getScale();
|
||||
}
|
||||
else if (Type.isValue("DistanceX")) {
|
||||
result = fabs(dimVec.x) / getViewPart()->getScale();
|
||||
}
|
||||
else {
|
||||
result = fabs(dimVec.y) / getViewPart()->getScale();
|
||||
}
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
arcPoints pts = m_arcPoints;
|
||||
result =
|
||||
pts.radius / getViewPart()->getScale(); // Projected BaseGeom is scaled for drawing
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
arcPoints pts = m_arcPoints;
|
||||
result = (pts.radius * 2.0)
|
||||
/ getViewPart()->getScale(); // Projected BaseGeom is scaled for drawing
|
||||
}
|
||||
else if (Type.isValue("Angle") || Type.isValue("Angle3Pt")) { // same as case "Angle"?
|
||||
anglePoints pts = m_anglePoints;
|
||||
Base::Vector3d vertex = pts.vertex();
|
||||
Base::Vector3d leg0 = pts.first() - vertex;
|
||||
Base::Vector3d leg1 = pts.second() - vertex;
|
||||
double legAngle = Base::toDegrees(leg0.GetAngle(leg1));
|
||||
result = legAngle;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
pointPair DrawViewDimension::getPointsOneEdge(ReferenceVector references)
|
||||
{
|
||||
// Base::Console().Message("DVD::getPointsOneEdge()\n");
|
||||
@@ -730,12 +764,12 @@ pointPair DrawViewDimension::getPointsOneEdge(ReferenceVector references)
|
||||
throw Base::RuntimeError(ssMessage.str());
|
||||
}
|
||||
TechDraw::GenericPtr generic = std::static_pointer_cast<TechDraw::Generic>(geom);
|
||||
// these points are from 2d geometry, so they are scaled and rotated
|
||||
return {generic->points[0], generic->points[1]};
|
||||
}
|
||||
|
||||
// this is a 3d object
|
||||
// get the endpoints of the edge in the DVP's coordinates
|
||||
Base::Vector3d edgeEnd0, edgeEnd1;
|
||||
TopoDS_Shape geometry = references.front().getGeometry();
|
||||
if (geometry.IsNull() || geometry.ShapeType() != TopAbs_EDGE) {
|
||||
throw Base::RuntimeError("Geometry for dimension reference is null.");
|
||||
@@ -845,7 +879,8 @@ pointPair DrawViewDimension::getPointsEdgeVert(ReferenceVector references)
|
||||
}
|
||||
|
||||
// get curve from edge
|
||||
double start, end; // curve parameters
|
||||
double start{0.0}; // curve parameters
|
||||
double end{0.0}; // curve parameters
|
||||
const Handle(Geom_Surface) hplane = new Geom_Plane(gp_Ax3());
|
||||
auto const occCurve =
|
||||
BRep_Tool::CurveOnPlane(edge->getOCCEdge(), hplane, TopLoc_Location(), start, end);
|
||||
@@ -860,10 +895,8 @@ pointPair DrawViewDimension::getPointsEdgeVert(ReferenceVector references)
|
||||
result.setExtensionLine(closestPoints(edge->getOCCEdge(), vertex->getOCCVertex()));
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
// unable to project
|
||||
return closestPoints(edge->getOCCEdge(), vertex->getOCCVertex());
|
||||
}
|
||||
}
|
||||
|
||||
// this is a 3d object
|
||||
@@ -974,8 +1007,8 @@ arcPoints DrawViewDimension::arcPointsFromBaseGeom(TechDraw::BaseGeomPtr base)
|
||||
else if (base && base->getGeomType() == TechDraw::GeomType::BSPLINE) {
|
||||
TechDraw::BSplinePtr spline = std::static_pointer_cast<TechDraw::BSpline>(base);
|
||||
if (spline->isCircle()) {
|
||||
bool arc;
|
||||
double rad;
|
||||
bool arc{false};
|
||||
double rad{0};
|
||||
Base::Vector3d center;
|
||||
// bool circ =
|
||||
GeometryUtils::getCircleParms(spline->getOCCEdge(), rad, center, arc);
|
||||
@@ -1141,7 +1174,8 @@ anglePoints DrawViewDimension::getAnglePointsTwoEdges(ReferenceVector references
|
||||
TechDraw::GenericPtr generic0 = std::static_pointer_cast<TechDraw::Generic>(geom0);
|
||||
TechDraw::GenericPtr generic1 = std::static_pointer_cast<TechDraw::Generic>(geom1);
|
||||
Base::Vector3d apex = generic0->apparentInter(generic1);
|
||||
Base::Vector3d farPoint0, farPoint1;
|
||||
Base::Vector3d farPoint0;
|
||||
Base::Vector3d farPoint1;
|
||||
// pick the end of generic0 farthest from the apex
|
||||
if ((generic0->getStartPoint() - apex).Length()
|
||||
> (generic0->getEndPoint() - apex).Length()) {
|
||||
@@ -1375,7 +1409,8 @@ int DrawViewDimension::getRefType() const
|
||||
int DrawViewDimension::getRefTypeSubElements(const std::vector<std::string>& subElements)
|
||||
{
|
||||
int refType = invalidRef;
|
||||
int refEdges = 0, refVertices = 0;
|
||||
int refEdges{0};
|
||||
int refVertices{0};
|
||||
|
||||
for (const auto& se : subElements) {
|
||||
if (DrawUtil::getGeomTypeFromName(se) == "Vertex") {
|
||||
@@ -1408,7 +1443,7 @@ int DrawViewDimension::getRefTypeSubElements(const std::vector<std::string>& sub
|
||||
//! validate 2D references - only checks if the target exists
|
||||
bool DrawViewDimension::checkReferences2D() const
|
||||
{
|
||||
// Base::Console().Message("DVD::checkReferences2d() - %s\n", getNameInDocument());
|
||||
// Base::Console().Message("DVD::checkReferences2d() - %s\n", getNameInDocument());
|
||||
const std::vector<App::DocumentObject*>& objects = References2D.getValues();
|
||||
if (objects.empty()) {
|
||||
return false;
|
||||
@@ -1425,21 +1460,21 @@ bool DrawViewDimension::checkReferences2D() const
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto& s : subElements) {
|
||||
if (s.empty()) {
|
||||
for (auto& sub : subElements) {
|
||||
if (sub.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int idx = DrawUtil::getIndexFromName(s);
|
||||
if (DrawUtil::getGeomTypeFromName(s) == "Edge") {
|
||||
int idx = DrawUtil::getIndexFromName(sub);
|
||||
if (DrawUtil::getGeomTypeFromName(sub) == "Edge") {
|
||||
TechDraw::BaseGeomPtr geom = getViewPart()->getGeomByIndex(idx);
|
||||
if (!geom) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (DrawUtil::getGeomTypeFromName(s) == "Vertex") {
|
||||
TechDraw::VertexPtr v = getViewPart()->getProjVertexByIndex(idx);
|
||||
if (!v) {
|
||||
else if (DrawUtil::getGeomTypeFromName(sub) == "Vertex") {
|
||||
TechDraw::VertexPtr vert = getViewPart()->getProjVertexByIndex(idx);
|
||||
if (!vert) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1456,13 +1491,12 @@ bool DrawViewDimension::hasBroken3dReferences() const
|
||||
const std::vector<App::DocumentObject*>& objects = References2D.getValues();
|
||||
const std::vector<std::string>& subElements = References2D.getSubValues();
|
||||
|
||||
if (objects.size() == 1 && objects3d.empty() && subElements.empty()) {
|
||||
// we have the reference to the View, but no 2d subelements or 3d objects
|
||||
// this means that the 3d references have been nulled out due to
|
||||
// object deletion and the reference will need to be rebuilt.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// if we have the reference to the View, but no 2d subelements or 3d objects
|
||||
// this means that the 3d references have been nulled out due to
|
||||
// object deletion and the reference will need to be rebuilt.
|
||||
return (objects.size() == 1 &&
|
||||
objects3d.empty() &&
|
||||
subElements.empty());
|
||||
}
|
||||
|
||||
|
||||
@@ -1477,28 +1511,20 @@ void DrawViewDimension::updateSavedGeometry()
|
||||
}
|
||||
std::vector<TopoShape> newGeometry;
|
||||
const std::vector<TopoShape> oldGeometry = SavedGeometry.getValues();
|
||||
// need to clean up old geometry objects here?
|
||||
// need to clean up old saved geometry objects here?
|
||||
|
||||
size_t iOldGeom(0);
|
||||
for (auto& entry : references) {
|
||||
if (entry.getSubName().empty()) {
|
||||
// view only reference has no geometry.
|
||||
continue;
|
||||
}
|
||||
if (entry.hasGeometry()) {
|
||||
newGeometry.push_back(entry.asTopoShape());
|
||||
newGeometry.push_back(entry.asCanonicalTopoShape());
|
||||
}
|
||||
else {
|
||||
// use old geometry entry? null shape? have to put something in the vector
|
||||
// so SavedGeometry and references stay in sync.
|
||||
if (iOldGeom < oldGeometry.size()) {
|
||||
newGeometry.push_back(oldGeometry.at(iOldGeom));
|
||||
}
|
||||
else {
|
||||
// have to put something in the vector so SavedGeometry and references stay in sync.
|
||||
newGeometry.push_back(Part::TopoShape());
|
||||
}
|
||||
}
|
||||
iOldGeom++;
|
||||
}
|
||||
if (!newGeometry.empty()) {
|
||||
SavedGeometry.setValues(newGeometry);
|
||||
@@ -1511,35 +1537,34 @@ void DrawViewDimension::updateSavedGeometry()
|
||||
std::vector<TopoShape> DrawViewDimension::getEdges(const TopoShape& inShape)
|
||||
{
|
||||
std::vector<TopoShape> ret;
|
||||
TopTools_IndexedMapOfShape M;
|
||||
TopTools_IndexedMapOfShape shapeMap;
|
||||
TopExp_Explorer Ex(inShape.getShape(), TopAbs_EDGE);
|
||||
while (Ex.More()) {
|
||||
M.Add(Ex.Current());
|
||||
shapeMap.Add(Ex.Current());
|
||||
Ex.Next();
|
||||
}
|
||||
|
||||
for (Standard_Integer k = 1; k <= M.Extent(); k++) {
|
||||
const TopoDS_Shape& shape = M(k);
|
||||
for (Standard_Integer k = 1; k <= shapeMap.Extent(); k++) {
|
||||
const TopoDS_Shape& shape = shapeMap(k);
|
||||
ret.push_back(TopoShape(shape));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// based on Part::TopoShapePyImp::getShapes
|
||||
std::vector<TopoShape> DrawViewDimension::getVertexes(const TopoShape& inShape)
|
||||
{
|
||||
std::vector<TopoShape> ret;
|
||||
TopTools_IndexedMapOfShape M;
|
||||
TopTools_IndexedMapOfShape shapeMap;
|
||||
TopExp_Explorer Ex(inShape.getShape(), TopAbs_VERTEX);
|
||||
while (Ex.More()) {
|
||||
M.Add(Ex.Current());
|
||||
shapeMap.Add(Ex.Current());
|
||||
Ex.Next();
|
||||
}
|
||||
|
||||
for (Standard_Integer k = 1; k <= M.Extent(); k++) {
|
||||
const TopoDS_Shape& shape = M(k);
|
||||
for (Standard_Integer k = 1; k <= shapeMap.Extent(); k++) {
|
||||
const TopoDS_Shape& shape = shapeMap(k);
|
||||
ret.push_back(TopoShape(shape));
|
||||
}
|
||||
|
||||
@@ -1555,38 +1580,38 @@ pointPair DrawViewDimension::closestPoints(TopoDS_Shape s1, TopoDS_Shape s2) con
|
||||
}
|
||||
int count = extss.NbSolution();
|
||||
if (count != 0) {
|
||||
gp_Pnt p = extss.PointOnShape1(1);
|
||||
result.first(Base::Vector3d(p.X(), p.Y(), p.Z()));
|
||||
p = extss.PointOnShape2(1);
|
||||
result.second(Base::Vector3d(p.X(), p.Y(), p.Z()));
|
||||
gp_Pnt point = extss.PointOnShape1(1);
|
||||
result.first(Base::Vector3d(point.X(), point.Y(), point.Z()));
|
||||
point = extss.PointOnShape2(1);
|
||||
result.second(Base::Vector3d(point.X(), point.Y(), point.Z()));
|
||||
} // TODO: else { explode }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// set the reference property from a reference vector
|
||||
void DrawViewDimension::setReferences2d(ReferenceVector refs)
|
||||
void DrawViewDimension::setReferences2d(ReferenceVector refsAll)
|
||||
{
|
||||
// Base::Console().Message("DVD::setReferences2d(%d)\n", refs.size());
|
||||
// Base::Console().Message("DVD::setReferences2d(%d)\n", refs.size());
|
||||
std::vector<App::DocumentObject*> objects;
|
||||
std::vector<std::string> subNames;
|
||||
if (objects.size() != subNames.size()) {
|
||||
throw Base::IndexError("DVD::setReferences2d - objects and subNames do not match.");
|
||||
}
|
||||
|
||||
for (size_t iRef = 0; iRef < refs.size(); iRef++) {
|
||||
objects.push_back(refs.at(iRef).getObject());
|
||||
subNames.push_back(refs.at(iRef).getSubName());
|
||||
for (auto& ref : refsAll) {
|
||||
objects.push_back(ref.getObject());
|
||||
subNames.push_back(ref.getSubName());
|
||||
}
|
||||
|
||||
References2D.setValues(objects, subNames);
|
||||
}
|
||||
|
||||
// set the reference property from a reference vector
|
||||
void DrawViewDimension::setReferences3d(ReferenceVector refs)
|
||||
void DrawViewDimension::setReferences3d(ReferenceVector refsAll)
|
||||
{
|
||||
// Base::Console().Message("DVD::setReferences3d()\n");
|
||||
if (refs.empty() && !References3D.getValues().empty()) {
|
||||
if (refsAll.empty() && !References3D.getValues().empty()) {
|
||||
// clear the property of any old links
|
||||
References3D.setValue(nullptr, nullptr);
|
||||
return;
|
||||
@@ -1597,17 +1622,17 @@ void DrawViewDimension::setReferences3d(ReferenceVector refs)
|
||||
throw Base::IndexError("DVD::setReferences3d - objects and subNames do not match.");
|
||||
}
|
||||
|
||||
for (size_t iRef = 0; iRef < refs.size(); iRef++) {
|
||||
objects.push_back(refs.at(iRef).getObject());
|
||||
subNames.push_back(refs.at(iRef).getSubName());
|
||||
for (auto& ref : refsAll) {
|
||||
objects.push_back(ref.getObject());
|
||||
subNames.push_back(ref.getSubName());
|
||||
// cache the referenced object
|
||||
m_3dObjectCache.insert(refs.at(iRef).getObject()->getNameInDocument());
|
||||
m_3dObjectCache.insert(ref.getObject()->getNameInDocument());
|
||||
// cache the parent object if available. Ideally, we would handle deletion
|
||||
// of a reference object in a slot for DocumentObject::signalDeletedObject,
|
||||
// but by the time we get the signal the document will have severed any links
|
||||
// between our object and its parents. So we need to cache the parent here while
|
||||
// we still have the link
|
||||
App::DocumentObject* firstParent = refs.at(iRef).getObject()->getFirstParent();
|
||||
App::DocumentObject* firstParent = ref.getObject()->getFirstParent();
|
||||
if (firstParent) {
|
||||
m_3dObjectCache.insert(firstParent->getNameInDocument());
|
||||
}
|
||||
@@ -1619,22 +1644,22 @@ void DrawViewDimension::setReferences3d(ReferenceVector refs)
|
||||
//! add Dimension 3D references to measurement
|
||||
void DrawViewDimension::setAll3DMeasurement()
|
||||
{
|
||||
// Base::Console().Message("DVD::setAll3dMeasurement()\n");
|
||||
// Base::Console().Message("DVD::setAll3dMeasurement()\n");
|
||||
measurement->clear();
|
||||
const std::vector<App::DocumentObject*>& Objs = References3D.getValues();
|
||||
const std::vector<std::string>& Subs = References3D.getSubValues();
|
||||
int end = Objs.size();
|
||||
int i = 0;
|
||||
for (; i < end; i++) {
|
||||
static_cast<void>(measurement->addReference3D(Objs.at(i), Subs.at(i)));
|
||||
int iObject = 0;
|
||||
for (; iObject < end; iObject++) {
|
||||
static_cast<void>(measurement->addReference3D(Objs.at(iObject), Subs.at(iObject)));
|
||||
// cache the referenced object
|
||||
m_3dObjectCache.insert(Objs.at(i)->getNameInDocument());
|
||||
m_3dObjectCache.insert(Objs.at(iObject)->getNameInDocument());
|
||||
// cache the parent object if available. Ideally, we would handle deletion
|
||||
// of a reference object in a slot for DocumentObject::signalDeletedObject,
|
||||
// but by the time we get the signal the document will have severed any links
|
||||
// between our object and its parents. So we need to cache the parent here while
|
||||
// we still have the link
|
||||
App::DocumentObject* firstParent = Objs.at(i)->getFirstParent();
|
||||
App::DocumentObject* firstParent = Objs.at(iObject)->getFirstParent();
|
||||
if (firstParent) {
|
||||
m_3dObjectCache.insert(firstParent->getNameInDocument());
|
||||
}
|
||||
@@ -1645,6 +1670,7 @@ void DrawViewDimension::setAll3DMeasurement()
|
||||
//! dimension.
|
||||
bool DrawViewDimension::validateReferenceForm() const
|
||||
{
|
||||
// Base::Console().Message("DVD::validateReferenceForm()\n");
|
||||
// we have either or both valid References3D and References2D
|
||||
ReferenceVector references = getEffectiveReferences();
|
||||
if (references.empty()) {
|
||||
@@ -1657,89 +1683,72 @@ bool DrawViewDimension::validateReferenceForm() const
|
||||
return false;
|
||||
}
|
||||
std::string subGeom = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
if (subGeom != "Edge") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return subGeom == "Edge";
|
||||
}
|
||||
else if (getRefType() == twoEdge) {
|
||||
if (getRefType() == twoEdge) {
|
||||
if (references.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom0 = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
std::string subGeom1 = DrawUtil::getGeomTypeFromName(references.back().getSubName());
|
||||
if (subGeom0 != "Edge" || subGeom1 != "Edge") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (subGeom0 == "Edge" && subGeom1 == "Edge");
|
||||
}
|
||||
else if (getRefType() == twoVertex) {
|
||||
|
||||
if (getRefType() == twoVertex) {
|
||||
if (references.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom0 = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
std::string subGeom1 = DrawUtil::getGeomTypeFromName(references.back().getSubName());
|
||||
if (subGeom0 != "Vertex" || subGeom1 != "Vertex") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (subGeom0 == "Vertex" && subGeom1 == "Vertex");
|
||||
}
|
||||
else if (getRefType() == vertexEdge) {
|
||||
|
||||
if (getRefType() == vertexEdge) {
|
||||
if (references.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom0 = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
std::string subGeom1 = DrawUtil::getGeomTypeFromName(references.back().getSubName());
|
||||
if ( (subGeom0 == "Vertex" && subGeom1 == "Edge") ||
|
||||
(subGeom0 == "Edge" && subGeom1 == "Vertex") ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return ( (subGeom0 == "Vertex" && subGeom1 == "Edge") ||
|
||||
(subGeom0 == "Edge" && subGeom1 == "Vertex") );
|
||||
}
|
||||
}
|
||||
else if (Type.isValue("Radius")) {
|
||||
|
||||
if (Type.isValue("Radius")) {
|
||||
if (references.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
if (subGeom != "Edge") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return subGeom == "Edge";
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
|
||||
if (Type.isValue("Diameter")) {
|
||||
if (references.size() != 1) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
if (subGeom != "Edge") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (subGeom == "Edge");
|
||||
}
|
||||
else if (Type.isValue("Angle")) {
|
||||
|
||||
if (Type.isValue("Angle")) {
|
||||
if (references.size() != 2) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom0 = DrawUtil::getGeomTypeFromName(references.front().getSubName());
|
||||
std::string subGeom1 = DrawUtil::getGeomTypeFromName(references.back().getSubName());
|
||||
if (subGeom0 != "Edge" || subGeom1 != "Edge") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (subGeom0 == "Edge" && subGeom1 == "Edge");
|
||||
}
|
||||
else if (Type.isValue("Angle3Pt")) {
|
||||
|
||||
if (Type.isValue("Angle3Pt")) {
|
||||
if (references.size() != 3) {
|
||||
return false;
|
||||
}
|
||||
std::string subGeom0 = DrawUtil::getGeomTypeFromName(references.at(0).getSubName());
|
||||
std::string subGeom1 = DrawUtil::getGeomTypeFromName(references.at(1).getSubName());
|
||||
std::string subGeom2 = DrawUtil::getGeomTypeFromName(references.at(2).getSubName());
|
||||
if (subGeom0 != "Vertex" || subGeom1 != "Vertex" || subGeom2 != "Vertex") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return (subGeom0 == "Vertex" && subGeom1 == "Vertex" && subGeom2 == "Vertex");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1899,11 +1908,9 @@ bool DrawViewDimension::has3DReferences() const
|
||||
// has arbitrary or nonzero tolerance
|
||||
bool DrawViewDimension::hasOverUnderTolerance() const
|
||||
{
|
||||
if (ArbitraryTolerances.getValue() || !DrawUtil::fpCompare(OverTolerance.getValue(), 0.0)
|
||||
|| !DrawUtil::fpCompare(UnderTolerance.getValue(), 0.0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (ArbitraryTolerances.getValue() ||
|
||||
!DrawUtil::fpCompare(OverTolerance.getValue(), 0.0) ||
|
||||
!DrawUtil::fpCompare(UnderTolerance.getValue(), 0.0));
|
||||
}
|
||||
|
||||
bool DrawViewDimension::showUnits() const
|
||||
@@ -1921,7 +1928,8 @@ std::string DrawViewDimension::getPrefixForDimType() const
|
||||
if (Type.isValue("Radius")) {
|
||||
return "R";
|
||||
}
|
||||
else if (Type.isValue("Diameter")) {
|
||||
|
||||
if (Type.isValue("Diameter")) {
|
||||
return std::string(Preferences::getPreferenceGroup("Dimensions")
|
||||
->GetASCII("DiameterSymbol", "\xe2\x8c\x80")); // Diameter symbol
|
||||
}
|
||||
@@ -1936,11 +1944,9 @@ std::string DrawViewDimension::getDefaultFormatSpec(bool isToleranceFormat) cons
|
||||
|
||||
bool DrawViewDimension::isExtentDim() const
|
||||
{
|
||||
constexpr int DimExtentLength{9};
|
||||
std::string name(getNameInDocument());
|
||||
if (name.substr(0, 9) == "DimExtent") {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (name.substr(0, DimExtentLength) == "DimExtent");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user