[TD]fix dimension autocorrect

- autocorrect was not handling scaled and rotated reference geometry
  properly.
This commit is contained in:
wandererfan
2024-05-05 20:38:14 -04:00
parent 15b612ebca
commit d2d93458e9
17 changed files with 701 additions and 563 deletions

View File

@@ -107,8 +107,6 @@ SET(Draw_SRCS
DimensionFormatter.h
DimensionAutoCorrect.cpp
DimensionAutoCorrect.h
GeometryMatcher.cpp
GeometryMatcher.h
DrawViewBalloon.cpp
DrawViewBalloon.h
DrawViewSection.cpp
@@ -201,6 +199,8 @@ SET(Geometry_SRCS
PropertyCosmeticVertexList.h
CosmeticExtension.cpp
CosmeticExtension.h
GeometryMatcher.cpp
GeometryMatcher.h
)
SET(Python_SRCS

View File

@@ -86,7 +86,6 @@ using DU = DrawUtil;
bool DimensionAutoCorrect::referencesHaveValidGeometry(std::vector<bool>& referenceState) const
{
// Base::Console().Message("DAC::referencesHaveValidGeometry()\n");
ReferenceVector refsAll = getDimension()->getEffectiveReferences();
const std::vector<Part::TopoShape> savedGeometry = getDimension()->SavedGeometry.getValues();
@@ -114,6 +113,7 @@ bool DimensionAutoCorrect::referencesHaveValidGeometry(std::vector<bool>& refere
result = false;
referenceState.emplace_back(false);
}
iRef++;
}
return result;
}
@@ -138,16 +138,6 @@ bool DimensionAutoCorrect::autocorrectReferences(std::vector<bool>& referenceSta
return false;
}
std::vector<Part::TopoShape> referenceGeometry;
for (auto& entry : refsAll) {
if (entry.hasGeometry()) {
referenceGeometry.push_back(entry.asTopoShape());
}
else {
referenceGeometry.push_back(Part::TopoShape());
}
}
size_t iRef {0};
for (const auto& state : referenceState) {
if (state) {
@@ -158,7 +148,7 @@ bool DimensionAutoCorrect::autocorrectReferences(std::vector<bool>& referenceSta
continue;
}
Part::TopoShape temp = savedGeometry.at(iRef);
const Part::TopoShape& temp = savedGeometry.at(iRef);
if (temp.isNull()) {
result = false;
referenceState.at(iRef) = false;
@@ -170,7 +160,6 @@ bool DimensionAutoCorrect::autocorrectReferences(std::vector<bool>& referenceSta
// this ref does not point to valid geometry or
// the geometry it points to does not match the saved geometry
ReferenceEntry fixedRef = refsAll.at(iRef);
// first, look for an exact match to the saved geometry
@@ -183,17 +172,17 @@ bool DimensionAutoCorrect::autocorrectReferences(std::vector<bool>& referenceSta
continue;
}
// we did not find an exact match, so check for an Similar match
// we did not find an exact match, so check for an similar match
success = fix1GeomSimilar(fixedRef, savedGeometry.at(iRef).getShape());
if (success) {
// we did find an Similar match
// we did find an similar match
referenceState.at(iRef) = true;
repairedRefs.push_back(fixedRef);
iRef++;
continue;
}
// we did not find an Similar match the geometry
// we did not find an similar match the geometry
result = false;
referenceState.at(iRef) = false;
repairedRefs.push_back(fixedRef);
@@ -204,60 +193,60 @@ bool DimensionAutoCorrect::autocorrectReferences(std::vector<bool>& referenceSta
return result;
}
//! fix a single reference with an exact match to geomToFix
bool DimensionAutoCorrect::fix1GeomExact(ReferenceEntry& refToFix, TopoDS_Shape geomToFix) const
//! fix a single reference with an exact match to geomToMatch
bool DimensionAutoCorrect::fix1GeomExact(ReferenceEntry& refToFix, const TopoDS_Shape &geomToMatch) const
{
// Base::Console().Message("DAC::fix1GeomExact()\n");
ReferenceEntry fixedRef = refToFix;
Part::TopoShape topoShapeToFix(geomToFix);
Part::TopoShape topoShapeToMatch(geomToMatch);
bool success {false};
if (refToFix.is3d()) {
if (!refToFix.getObject() && m_3dObjectCache.empty()) {
return false;
}
if (geomToFix.ShapeType() == TopAbs_VERTEX) {
success = findExactVertex3d(refToFix, topoShapeToFix);
if (geomToMatch.ShapeType() == TopAbs_VERTEX) {
success = findExactVertex3d(refToFix, topoShapeToMatch);
}
else {
success = findExactEdge3d(refToFix, topoShapeToFix);
success = findExactEdge3d(refToFix, topoShapeToMatch);
}
}
else {
if (geomToFix.ShapeType() == TopAbs_VERTEX) {
success = findExactVertex2d(refToFix, topoShapeToFix);
if (geomToMatch.ShapeType() == TopAbs_VERTEX) {
success = findExactVertex2d(refToFix, topoShapeToMatch);
}
else {
success = findExactEdge2d(refToFix, topoShapeToFix);
success = findExactEdge2d(refToFix, topoShapeToMatch);
}
}
return success;
}
//! fix a single reference with an Similar match to geomToFix
bool DimensionAutoCorrect::fix1GeomSimilar(ReferenceEntry& refToFix, TopoDS_Shape geomToFix) const
//! fix a single reference with an Similar match to geomToMatch
bool DimensionAutoCorrect::fix1GeomSimilar(ReferenceEntry& refToFix, const TopoDS_Shape &geomToMatch) const
{
// Base::Console().Message("DAC::fix1GeomSimilar()\n");
Part::TopoShape topoShapeToFix(geomToFix);
Part::TopoShape topoShapeToMatch(geomToMatch);
bool success {false};
if (refToFix.is3d()) {
if (!refToFix.getObject() && m_3dObjectCache.empty()) {
// can't fix this. nothing to compare.
return false;
}
if (geomToFix.ShapeType() == TopAbs_VERTEX) {
success = findSimilarVertex3d(refToFix, topoShapeToFix);
if (geomToMatch.ShapeType() == TopAbs_VERTEX) {
success = findSimilarVertex3d(refToFix, topoShapeToMatch);
}
else {
success = findSimilarEdge3d(refToFix, topoShapeToFix);
success = findSimilarEdge3d(refToFix, topoShapeToMatch);
}
}
else {
if (geomToFix.ShapeType() == TopAbs_VERTEX) {
success = findSimilarVertex2d(refToFix, topoShapeToFix);
if (geomToMatch.ShapeType() == TopAbs_VERTEX) {
success = findSimilarVertex2d(refToFix, topoShapeToMatch);
}
else {
success = findSimilarEdge2d(refToFix, topoShapeToFix);
success = findSimilarEdge2d(refToFix, topoShapeToMatch);
}
}
return success;
@@ -267,7 +256,7 @@ bool DimensionAutoCorrect::fix1GeomSimilar(ReferenceEntry& refToFix, TopoDS_Shap
//! search the view for a 2d vertex that is the same as the saved reference geometry
//! and return a reference pointing to the matching vertex
bool DimensionAutoCorrect::findExactVertex2d(ReferenceEntry& refToFix,
Part::TopoShape refGeom) const
const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findExactVertex2d()\n");
getMatcher()->setPointTolerance(EWTOLERANCE);
@@ -284,32 +273,29 @@ bool DimensionAutoCorrect::findExactVertex2d(ReferenceEntry& refToFix,
return false;
}
//! search the view for a 2d edge that is the same as the saved reference geometry
//! search the view for a 2d edge that is the same as the saved reference geometry (from DVD::SavedGeometry)
//! and return a reference pointing to the matching edge.
bool DimensionAutoCorrect::findExactEdge2d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const
bool DimensionAutoCorrect::findExactEdge2d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findExactEdge2d()\n");
double scale = getDimension()->getViewPart()->getScale();
BaseGeomPtrVector gEdgeAll = getDimension()->getViewPart()->getEdgeGeometry();
int iEdge {0};
for (auto& edge : gEdgeAll) {
Part::TopoShape temp = edge->asTopoShape(scale);
bool isSame = getMatcher()->compareGeometry(refGeom, temp);
if (isSame) {
refToFix.setSubName(std::string("Edge") + std::to_string(iEdge));
auto refObj = refToFix.getObject();
auto refDvp = dynamic_cast<TechDraw::DrawViewPart*>(refObj);
if (refDvp) {
ReferenceEntry fixedRef = searchViewForExactEdge(refDvp, refGeom);
if (fixedRef.getObject()) {
refToFix = fixedRef;
return true;
}
iEdge++;
}
// no match, return the input reference
// no match
return false;
}
//! search the model for a 3d vertex that is the same as the saved reference geometry
//! and return a reference pointing to the matching vertex
bool DimensionAutoCorrect::findExactVertex3d(ReferenceEntry& refToFix,
Part::TopoShape refGeom) const
const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findExactVertex3d()\n");
getMatcher()->setPointTolerance(EWTOLERANCE);
@@ -339,7 +325,7 @@ bool DimensionAutoCorrect::findExactVertex3d(ReferenceEntry& refToFix,
//! search the model for a 3d edge that is the same as the saved reference geometry
//! and return a reference pointing to the matching edge.
bool DimensionAutoCorrect::findExactEdge3d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const
bool DimensionAutoCorrect::findExactEdge3d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findExactEdge3d() - cache: %d\n", m_3dObjectCache.size());
// first, try to find a match in the referenced object
@@ -375,24 +361,24 @@ bool DimensionAutoCorrect::findExactEdge3d(ReferenceEntry& refToFix, Part::TopoS
//! search the view for a vertex that is within a tolerance of the saved reference geometry
//! and return a reference pointing to the matching vertex
bool DimensionAutoCorrect::findSimilarVertex2d(ReferenceEntry& refToFix,
Part::TopoShape refGeom) const
const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findSimilarVertex2d()\n");
(void)refToFix;
(void)refGeom;
Base::Console().Message("DAC::findSimilarVertex2d is not implemented yet\n");
// Base::Console().Message("DAC::findSimilarVertex2d is not implemented yet\n");
return false;
}
//! search the view for a 2d edge that is similar to the saved reference geometry
//! and return a reference pointing to the similar edge.
bool DimensionAutoCorrect::findSimilarEdge2d(ReferenceEntry& refToFix,
Part::TopoShape refGeom) const
const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findSimilarEdge2d()\n");
(void)refToFix;
(void)refGeom;
Base::Console().Message("DAC::findSimilarEdge2d is not implemented yet\n");
// Base::Console().Message("DAC::findSimilarEdge2d is not implemented yet\n");
return false;
}
@@ -400,12 +386,12 @@ bool DimensionAutoCorrect::findSimilarEdge2d(ReferenceEntry& refToFix,
//! a tolerance of the saved reference geometry and return a reference pointing
//! to the matching vertex
bool DimensionAutoCorrect::findSimilarVertex3d(ReferenceEntry& refToFix,
Part::TopoShape refGeom) const
const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findSimilarVertex3d()\n");
(void)refToFix;
(void)refGeom;
Base::Console().Message("DAC::findSimilarVertex3d is not implemented yet\n");
// Base::Console().Message("DAC::findSimilarVertex3d is not implemented yet\n");
return false;
}
@@ -413,20 +399,21 @@ bool DimensionAutoCorrect::findSimilarVertex3d(ReferenceEntry& refToFix,
//! similar to the saved reference geometry and return a reference pointing
//! to the similar edge
bool DimensionAutoCorrect::findSimilarEdge3d(ReferenceEntry& refToFix,
Part::TopoShape refGeom) const
const Part::TopoShape& refGeom) const
{
// Base::Console().Message("DAC::findSimilarEdge3d(%s)\n", refToFix.getObjectName().c_str());
(void)refToFix;
(void)refGeom;
Base::Console().Message("DAC::findSimilarEdge3d is not implemented yet\n");
// Base::Console().Message("DAC::findSimilarEdge3d is not implemented yet\n");
return false;
}
//! compare the geometry pointed to by a reference to the corresponding saved geometry
bool DimensionAutoCorrect::isMatchingGeometry(ReferenceEntry ref,
Part::TopoShape savedGeometry) const
bool DimensionAutoCorrect::isMatchingGeometry(const ReferenceEntry& ref,
const Part::TopoShape& savedGeometry) const
{
Part::TopoShape temp = ref.asTopoShape();
// Base::Console().Message("DAC::isMatchingGeometry()\n");
Part::TopoShape temp = ref.asCanonicalTopoShape();
if (temp.isNull()) {
// this shouldn't happen as we already know that this ref points to valid geometry
return false;
@@ -443,7 +430,7 @@ bool DimensionAutoCorrect::isMatchingGeometry(ReferenceEntry ref,
//! an exact match for phase 1 (GeometryMatcher), but in phase 2 (GeometryGuesser)
//! a similar match will be allowed.
ReferenceEntry DimensionAutoCorrect::searchObjForVert(App::DocumentObject* obj,
Part::TopoShape refVertex,
const Part::TopoShape& refVertex,
bool exact) const
{
(void)exact;
@@ -455,7 +442,7 @@ ReferenceEntry DimensionAutoCorrect::searchObjForVert(App::DocumentObject* obj,
auto vertsAll = getDimension()->getVertexes(shape3d);
size_t iVert {1};
for (auto& vert : vertsAll) {
bool isSame = getMatcher()->compareGeometry(refVertex, vert);
bool isSame = getMatcher()->compareGeometry(vert, refVertex);
if (isSame) {
auto newSubname = std::string("Vertex") + std::to_string(iVert);
return {obj, newSubname, getDimension()->getDocument()};
@@ -469,18 +456,19 @@ ReferenceEntry DimensionAutoCorrect::searchObjForVert(App::DocumentObject* obj,
//! search View (2d part display) for a match to refVertex. This can be an
//! exact or Similar match depending on the setting of exact.
ReferenceEntry DimensionAutoCorrect::searchViewForVert(DrawViewPart* obj,
Part::TopoShape refVertex,
const Part::TopoShape& refVertex,
bool exact) const
{
// Base::Console().Message("DAC::searchViewForVert()\n");
(void)exact;
double scale = getDimension()->getViewPart()->getScale();
std::vector<TechDraw::VertexPtr> gVertexAll =
getDimension()->getViewPart()->getVertexGeometry();
getMatcher()->setPointTolerance(EWTOLERANCE);
int iVertex = 0;
for (auto& vert : gVertexAll) {
Part::TopoShape temp = vert->asTopoShape(scale);
bool isSame = getMatcher()->compareGeometry(refVertex, temp);
// vert is in display form - scaled and rotated
Part::TopoShape temp = ReferenceEntry::asCanonicalTopoShape(vert->asTopoShape(), *obj);
bool isSame = getMatcher()->compareGeometry(temp, refVertex);
if (isSame) {
auto newSubname = std::string("Vertex") + std::to_string(iVertex);
return {obj, newSubname, getDimension()->getDocument()};
@@ -492,14 +480,15 @@ ReferenceEntry DimensionAutoCorrect::searchViewForVert(DrawViewPart* obj,
//! search View (2d part display) for an exact match to refEdge.
ReferenceEntry DimensionAutoCorrect::searchViewForExactEdge(DrawViewPart* obj,
Part::TopoShape refEdge) const
const Part::TopoShape& refEdge) const
{
// Base::Console().Message("DAC::searchViewForExactEdge()\n");
double scale = getDimension()->getViewPart()->getScale();
auto gEdgeAll = getDimension()->getViewPart()->getEdgeGeometry();
int iEdge {0};
for (auto& edge : gEdgeAll) {
Part::TopoShape temp = edge->asTopoShape(scale);
// edge is scaled and rotated. we need it in the same scale/rotate state as
// the reference edge in order to match.
Part::TopoShape temp = ReferenceEntry::asCanonicalTopoShape(edge->asTopoShape(), *obj);
bool isSame = getMatcher()->compareGeometry(refEdge, temp);
if (isSame) {
auto newSubname = std::string("Edge") + std::to_string(iEdge);
@@ -513,7 +502,7 @@ ReferenceEntry DimensionAutoCorrect::searchViewForExactEdge(DrawViewPart* obj,
//! search View (2d part display) for an edge that is similar to refEdge
ReferenceEntry DimensionAutoCorrect::searchViewForSimilarEdge(DrawViewPart* obj,
Part::TopoShape refEdge) const
const Part::TopoShape& refEdge) const
{
// Base::Console().Message("DAC::searchViewForSimilarEdge()\n");
(void)obj;
@@ -525,7 +514,7 @@ ReferenceEntry DimensionAutoCorrect::searchViewForSimilarEdge(DrawViewPart* obj,
//! search model for for a 3d edge that is a match to refEdge
//! note that only the exact match is implemented in phase 1
ReferenceEntry DimensionAutoCorrect::searchObjForEdge(App::DocumentObject* obj,
Part::TopoShape refEdge,
const Part::TopoShape& refEdge,
bool exact) const
{
// Base::Console().Message("DAC::searchObjForEdge(%s)\n", obj->Label.getValue());
@@ -533,13 +522,12 @@ ReferenceEntry DimensionAutoCorrect::searchObjForEdge(App::DocumentObject* obj,
auto shape3d = Part::Feature::getShape(obj);
if (shape3d.IsNull()) {
// how to handle this?
// Base::Console().Message("DAC::searchObjForEdge - object shape is null\n");
return {};
}
auto edgesAll = getDimension()->getEdges(shape3d);
size_t iEdge {1};
for (auto& edge : edgesAll) {
bool isSame = getMatcher()->compareGeometry(refEdge, edge);
bool isSame = getMatcher()->compareGeometry(edge, refEdge);
if (isSame) {
auto newSubname = std::string("Edge") + std::to_string(iEdge);
return {obj, newSubname, getDimension()->getDocument()};
@@ -563,7 +551,7 @@ bool DimensionAutoCorrect::fixBrokenReferences(ReferenceVector& fixedReferences)
continue;
}
//
TopoDS_Shape geomShape = geom.getShape();
const TopoDS_Shape& geomShape = geom.getShape();
for (auto& objectName : m_3dObjectCache) {
auto object3d = getDimension()->getDocument()->getObject(objectName.c_str());
if (!object3d) {
@@ -594,3 +582,4 @@ GeometryMatcher* DimensionAutoCorrect::getMatcher() const
{
return getDimension()->getMatcher();
}

View File

@@ -42,12 +42,9 @@ class GeometryMatcher;
class TechDrawExport DimensionAutoCorrect
{
public:
DimensionAutoCorrect()
{}
explicit DimensionAutoCorrect(DrawViewDimension* dim)
{
m_dimension = dim;
}
DimensionAutoCorrect() = default;
explicit DimensionAutoCorrect(DrawViewDimension* dim) :
m_dimension(dim) {}
~DimensionAutoCorrect() = default;
bool referencesHaveValidGeometry(std::vector<bool>& referenceState) const;
@@ -61,31 +58,30 @@ public:
bool fixBrokenReferences(ReferenceVector& fixedReferences) const;
private:
bool fix1GeomExact(ReferenceEntry& refToFix, TopoDS_Shape geomToFix) const;
bool fix1GeomSimilar(ReferenceEntry& refToFix, TopoDS_Shape geomToFix) const;
bool fix1GeomExact(ReferenceEntry& refToFix, const TopoDS_Shape& geomToMatch) const;
bool fix1GeomSimilar(ReferenceEntry& refToFix, const TopoDS_Shape& geomToMatch) const;
bool findExactVertex2d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findExactEdge2d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findExactVertex3d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findExactEdge3d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findExactVertex2d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findExactEdge2d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findExactVertex3d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findExactEdge3d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findSimilarVertex2d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findSimilarEdge2d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findSimilarVertex3d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findSimilarEdge3d(ReferenceEntry& refToFix, Part::TopoShape refGeom) const;
bool findSimilarVertex2d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findSimilarEdge2d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findSimilarVertex3d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
bool findSimilarEdge3d(ReferenceEntry& refToFix, const Part::TopoShape& refGeom) const;
ReferenceEntry
searchObjForVert(App::DocumentObject* obj, Part::TopoShape refVertex, bool exact = true) const;
searchObjForVert(App::DocumentObject* obj, const Part::TopoShape& refVertex, bool exact = true) const;
ReferenceEntry
searchViewForVert(DrawViewPart* obj, Part::TopoShape refVertex, bool exact = true) const;
searchViewForVert(DrawViewPart* obj, const Part::TopoShape& refVertex, bool exact = true) const;
ReferenceEntry
searchObjForEdge(App::DocumentObject* obj, Part::TopoShape refEdge, bool exact = true) const;
searchObjForEdge(App::DocumentObject* obj, const Part::TopoShape& refEdge, bool exact = true) const;
ReferenceEntry searchViewForExactEdge(DrawViewPart* obj, Part::TopoShape refEdge) const;
ReferenceEntry searchViewForSimilarEdge(DrawViewPart* obj, Part::TopoShape refEdge) const;
ReferenceEntry searchViewForExactEdge(DrawViewPart* obj, const Part::TopoShape& refEdge) const;
ReferenceEntry searchViewForSimilarEdge(DrawViewPart* obj, const Part::TopoShape& refEdge) const;
bool isMatchingGeometry(ReferenceEntry ref, Part::TopoShape savedGeometry) const;
bool isMatchingGeometry(const ReferenceEntry& ref, const Part::TopoShape& savedGeometry) const;
DrawViewDimension* getDimension() const
{
@@ -93,7 +89,7 @@ private:
}
GeometryMatcher* getMatcher() const;
DrawViewDimension* m_dimension;
DrawViewDimension* m_dimension{nullptr};
std::set<std::string> m_3dObjectCache;
};

View File

@@ -28,6 +28,7 @@
#endif
#include <Base/Console.h>
#include <Base/Tools.h>
#include "DimensionGeometry.h"
#include "DrawUtil.h"
@@ -117,6 +118,43 @@ void pointPair::dump(const std::string& text) const
DU::formatVector(first()).c_str(), DU::formatVector(second()).c_str());
}
//! return unscaled, unrotated version of this pointPair. caller is responsible for
//! for ensuring this pointPair is in scaled, rotated form before calling this method.
pointPair pointPair::toCanonicalForm(DrawViewPart* dvp) const
{
pointPair result;
// invert points?
result.m_first = CosmeticVertex::makeCanonicalPoint(dvp, m_first);
result.m_second = CosmeticVertex::makeCanonicalPoint(dvp, m_second);
result.m_overrideFirst = CosmeticVertex::makeCanonicalPoint(dvp, m_overrideFirst);
result.m_overrideSecond = CosmeticVertex::makeCanonicalPoint(dvp, m_overrideSecond);
return result;
}
//! return scaled and rotated version of this pointPair. caller is responsible for
//! for ensuring this pointPair is in canonical form before calling this method.
pointPair pointPair::toDisplayForm(DrawViewPart* dvp) const
{
pointPair result;
// invert points?
result.m_first = m_first * dvp->getScale();
result.m_second = m_second * dvp->getScale();
result.m_overrideFirst = m_overrideFirst * dvp->getScale();
result.m_overrideSecond = m_overrideSecond * dvp->getScale();
auto rotationDeg = dvp->Rotation.getValue();
if (rotationDeg != 0.0) {
auto rotationRad = Base::toRadians(rotationDeg);
result.m_first.RotateZ(rotationRad);
result.m_second.RotateZ(rotationRad);
result.m_overrideFirst.RotateZ(rotationRad);
result.m_overrideSecond.RotateZ(rotationRad);
}
return result;
}
anglePoints::anglePoints()
{
m_ends.first(Base::Vector3d(0.0, 0.0, 0.0));
@@ -168,6 +206,30 @@ void anglePoints::invertY()
m_vertex = DU::invertY(m_vertex);
}
//! return unscaled, unrotated version of this anglePoints. caller is responsible for
//! for ensuring this anglePoints is in scaled, rotated form before calling this method.
anglePoints anglePoints::toCanonicalForm(DrawViewPart* dvp) const
{
anglePoints result;
result.m_ends = m_ends.toCanonicalForm(dvp);
result.m_vertex = CosmeticVertex::makeCanonicalPoint(dvp, m_vertex);
return result;
}
//! return scaled and rotated version of this anglePoints. caller is responsible for
//! for ensuring this anglePoints is in canonical form before calling this method.
anglePoints anglePoints::toDisplayForm(DrawViewPart* dvp) const
{
anglePoints result;
result.m_ends = m_ends.toDisplayForm(dvp);
result.m_vertex = m_vertex * dvp->getScale();
auto rotationDeg = dvp->Rotation.getValue();
if (rotationDeg != 0.0) {
auto rotationRad = Base::toRadians(rotationDeg);
result.m_vertex.RotateZ(rotationRad);
}
return result;
}
void anglePoints::dump(const std::string& text) const
{
Base::Console().Message("anglePoints - %s\n", text.c_str());
@@ -252,6 +314,39 @@ void arcPoints::invertY()
midArc = DU::invertY(midArc);
}
//! return scaled and rotated version of this arcPoints. caller is responsible for
//! for ensuring this arcPoints is in canonical form before calling this method.
arcPoints arcPoints::toDisplayForm(DrawViewPart* dvp) const
{
arcPoints result;
result.onCurve = onCurve.toDisplayForm(dvp);
result.arcEnds = arcEnds.toDisplayForm(dvp);
result.center = center * dvp->getScale();
result.midArc = midArc * dvp->getScale();
result.radius = radius * dvp->getScale();
auto rotationDeg = dvp->Rotation.getValue();
if (rotationDeg != 0.0) {
auto rotationRad = Base::toRadians(rotationDeg);
result.center.RotateZ(rotationRad);
result.midArc.RotateZ(rotationRad);
}
return result;
}
//! return unscaled, unrotated version of this arcPoints. caller is responsible for
//! for ensuring this arcPoints is in scaled, rotated form before calling this method.
arcPoints arcPoints::toCanonicalForm(DrawViewPart* dvp) const
{
arcPoints result;
result.onCurve = onCurve.toCanonicalForm(dvp);
result.arcEnds = arcEnds.toCanonicalForm(dvp);
result.center = CosmeticVertex::makeCanonicalPoint(dvp, center);
result.midArc = CosmeticVertex::makeCanonicalPoint(dvp, midArc);
result.radius = radius / dvp->getScale();
return result;
}
void arcPoints::dump(const std::string& text) const
{
Base::Console().Message("arcPoints - %s\n", text.c_str());

View File

@@ -79,6 +79,10 @@ public:
void scale(double factor);
void dump(const std::string& text) const;
pointPair toCanonicalForm(DrawViewPart* dvp) const;
pointPair toDisplayForm(DrawViewPart* dvp) const;
private:
Base::Vector3d m_first;
Base::Vector3d m_second;
@@ -115,6 +119,10 @@ public:
void invertY();
void dump(const std::string& text) const;
anglePoints toCanonicalForm(DrawViewPart* dvp) const;
anglePoints toDisplayForm(DrawViewPart* dvp) const;
private:
pointPair m_ends;
Base::Vector3d m_vertex;
@@ -135,6 +143,9 @@ public:
void invertY();
void dump(const std::string& text) const;
arcPoints toCanonicalForm(DrawViewPart* dvp) const;
arcPoints toDisplayForm(DrawViewPart* dvp) const;
//TODO: setters and getters
bool isArc;
double radius;

View File

@@ -42,9 +42,11 @@
#include "DrawUtil.h"
#include "DrawViewPart.h"
#include "ShapeUtils.h"
#include "CosmeticVertex.h"
using namespace TechDraw;
using DU = DrawUtil;
using SU = ShapeUtils;
ReferenceEntry::ReferenceEntry( App::DocumentObject* docObject, std::string subName, App::Document* document)
@@ -60,6 +62,7 @@ ReferenceEntry::ReferenceEntry( App::DocumentObject* docObject, std::string subN
}
}
ReferenceEntry::ReferenceEntry(const ReferenceEntry& other)
{
setObject(other.getObject());
@@ -72,6 +75,9 @@ ReferenceEntry::ReferenceEntry(const ReferenceEntry& other)
ReferenceEntry& ReferenceEntry::operator=(const ReferenceEntry& otherRef)
{
if (this == &otherRef) {
return *this;
}
setObject(otherRef.getObject());
setSubName(otherRef.getSubName());
setObjectName(otherRef.getObjectName());
@@ -87,51 +93,19 @@ TopoDS_Shape ReferenceEntry::getGeometry() const
// first, make sure the object has not been deleted!
App::DocumentObject* obj = getDocument()->getObject(getObjectName().c_str());
if (!obj) {
Base::Console().Message("RE::getGeometry - %s no longer exists!\n", getObjectName().c_str());
return {};
}
if (getSubName().empty()) {
Base::Console().Message("RE::getGeometry - Reference has no subelement!\n");
return {};
}
if ( getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) ) {
// Base::Console().Message("RE::getGeometry - getting 2d geometry\n");
std::string gType;
try {
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
gType = geomType();
if (gType == "Vertex") {
// getVertex throws on not found, but we want to return null
// shape
auto vgeom = dvp->getVertex(getSubName());
if (!vgeom) {
return {};
}
return vgeom->getOCCVertex();
}
if (gType == "Edge") {
auto egeom = dvp->getEdge(getSubName());
if (!egeom) {
return {};
}
return egeom->getOCCEdge();
}
if (gType == "Face") {
auto fgeom = dvp->getFace(getSubName());
if (!fgeom) {
return {};
}
return fgeom->toOccFace();
}
}
catch (...) {
Base::Console().Message("RE::getGeometry - no shape for dimension 2d reference - gType: **%s**\n", gType.c_str());
return {};
}
// 2d geometry from DrawViewPart will be rotated and scaled
return getGeometry2d();
}
// 3d geometry
Part::TopoShape shape = Part::Feature::getTopoShape(getObject());
auto geoFeat = dynamic_cast<App::GeoFeature*>(getObject());
if (geoFeat) {
@@ -145,6 +119,48 @@ TopoDS_Shape ReferenceEntry::getGeometry() const
return shape.getSubShape(getSubName().c_str());
}
//! get a shape for this 2d reference
TopoDS_Shape ReferenceEntry::getGeometry2d() const
{
// Base::Console().Message("RE::getGeometry2d()\n");
std::string gType;
try {
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject()); //NOLINT cppcoreguidelines-pro-type-static-cast-downcast
gType = geomType();
if (gType == "Vertex") {
// getVertex throws on not found, but we want to return null
// shape
auto vgeom = dvp->getVertex(getSubName());
if (!vgeom) {
return {};
}
return vgeom->getOCCVertex();
}
if (gType == "Edge") {
auto egeom = dvp->getEdge(getSubName());
if (!egeom) {
return {};
}
return egeom->getOCCEdge();
}
if (gType == "Face") {
auto fgeom = dvp->getFace(getSubName());
if (!fgeom) {
return {};
}
return fgeom->toOccFace();
}
}
catch (...) {
Base::Console().Message("RE::getGeometry2d - no shape for dimension 2d reference - gType: **%s**\n", gType.c_str());
return {};
}
return {};
}
std::string ReferenceEntry::getSubName(bool longForm) const
{
if (longForm) {
@@ -158,6 +174,7 @@ std::string ReferenceEntry::getSubName(bool longForm) const
return workingSubName;
}
App::DocumentObject* ReferenceEntry::getObject() const
{
if (!getDocument()) {
@@ -171,13 +188,14 @@ App::DocumentObject* ReferenceEntry::getObject() const
return obj;
}
//! return the reference geometry as a Part::TopoShape.
Part::TopoShape ReferenceEntry::asTopoShape() const
{
// Base::Console().Message("RE::asTopoShape()\n");
// Base::Console().Message("RE::asTopoShape()\n");
TopoDS_Shape geom = getGeometry();
if (geom.IsNull()) {
// throw Base::RuntimeError("Dimension Reference has null geometry");
Base::Console().Message("RE::asTopoShape - reference geometry is null\n");
return {};
}
if (geom.ShapeType() == TopAbs_VERTEX) {
@@ -191,28 +209,48 @@ Part::TopoShape ReferenceEntry::asTopoShape() const
throw Base::RuntimeError("Dimension Reference has unsupported geometry");
}
Part::TopoShape ReferenceEntry::asTopoShapeVertex(TopoDS_Vertex& vert) const
//! returns unscaled, unrotated version of inShape. inShape is assumed to be a 2d shape, but this is not enforced.
Part::TopoShape ReferenceEntry::asCanonicalTopoShape() const
{
Base::Vector3d point = DU::toVector3d(BRep_Tool::Pnt(vert));
if (!is3d()) {
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
point = point / dvp->getScale();
// Base::Console().Message("RE::asCanonicalTopoShape()\n");
if (is3d()) {
return asTopoShape();
}
BRepBuilderAPI_MakeVertex mkVert(DU::togp_Pnt(point));
return { mkVert.Vertex() };
// this is a 2d reference
auto dvp = static_cast<DrawViewPart*>(getObject()); //NOLINT cppcoreguidelines-pro-type-static-cast-downcast
auto rawTopoShape = asTopoShape();
return ReferenceEntry::asCanonicalTopoShape(rawTopoShape, *dvp);
}
Part::TopoShape ReferenceEntry::asTopoShapeEdge(TopoDS_Edge &edge) const
//! static public method returns unscaled, unrotated version of inShape. inShape is assumed to be a 2d shape,
//! but this is not enforced. 3d shapes should not be made canonical.
//! 2d shapes are inverted in Y direction and need to be inverted before and after rotation
//! operations.
Part::TopoShape ReferenceEntry::asCanonicalTopoShape(const Part::TopoShape& inShape, const DrawViewPart& dvp)
{
// 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
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
TopoDS_Shape unscaledShape = ShapeUtils::scaleShape(edge, 1.0 / dvp->getScale());
unscaledEdge = TopoDS::Edge(unscaledShape);
// Base::Console().Message("RE::(static)asCanonicalTopoShape()\n");
gp_Ax2 OXYZ;
auto unscaledShape = SU::scaleShape(inShape.getShape(), 1.0 / dvp.getScale());
if (dvp.Rotation.getValue() != 0.0) {
auto rotationDeg = dvp.Rotation.getValue();
unscaledShape = SU::invertGeometry(unscaledShape);
unscaledShape = SU::rotateShape(unscaledShape, OXYZ, -rotationDeg);
unscaledShape = SU::invertGeometry(unscaledShape);
}
return { unscaledEdge };
return {unscaledShape};
}
Part::TopoShape ReferenceEntry::asTopoShapeVertex(const TopoDS_Vertex& vert)
{
return { vert };
}
Part::TopoShape ReferenceEntry::asTopoShapeEdge(const TopoDS_Edge &edge)
{
return { edge };
}
std::string ReferenceEntry::geomType() const
@@ -226,27 +264,22 @@ bool ReferenceEntry::isWholeObject() const
return getSubName().empty();
}
//! true if this reference point to 3d model geometry
bool ReferenceEntry::is3d() const
{
if (getObject() &&
getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) &&
!getSubName().empty()) {
// this is a well formed 2d reference
if (!getObject()) {
// we should really fail here?
return false;
}
if (getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
return false;
}
if (getObject() &&
getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) &&
getSubName().empty()) {
// this is a broken 3d reference, so it should be treated as 3d
return true;
}
// either we have no object or we have an object and it is a 3d object
return true;
}
//! check if this reference has valid geometry in the model
//! true if the target of this reference has a shape
bool ReferenceEntry::hasGeometry() const
{
// Base::Console().Message("RE::hasGeometry()\n");
@@ -256,33 +289,38 @@ bool ReferenceEntry::hasGeometry() const
if ( getObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()) ) {
// 2d reference
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject());
if (getSubName().empty()) {
return false;
}
int geomNumber = DU::getIndexFromName(getSubName());
std::string gType = geomType();
if (gType == "Vertex") {
auto vert = dvp->getProjVertexByIndex(geomNumber);
if (vert) {
return true;
}
} else if (gType == "Edge") {
auto edge = dvp->getGeomByIndex(geomNumber);
if (edge) {
return true;
}
}
// if we ever have dimensions for faces, add something here.
return false;
return hasGeometry2d();
}
// 3d reference
auto shape = Part::Feature::getTopoShape(getObject());
auto subShape = shape.getSubShape(getSubName().c_str());
if (!subShape.IsNull()) {
return true;
}
return !subShape.IsNull();
}
//! check if this 2d reference has valid geometry in the model
bool ReferenceEntry::hasGeometry2d() const
{
auto dvp = static_cast<TechDraw::DrawViewPart*>(getObject()); //NOLINT cppcoreguidelines-pro-type-static-cast-downcast
if (getSubName().empty()) {
return false;
}
int geomNumber = DU::getIndexFromName(getSubName());
std::string gType = geomType();
if (gType == "Vertex") {
auto vert = dvp->getProjVertexByIndex(geomNumber);
if (vert) {
return true;
}
} else if (gType == "Edge") {
auto edge = dvp->getGeomByIndex(geomNumber);
if (edge) {
return true;
}
}
return false;
}

View File

@@ -47,12 +47,13 @@ class TopoShape;
namespace TechDraw
{
class DrawViewPart;
//a convenient way of handling object+subName references
class TechDrawExport ReferenceEntry
{
public:
ReferenceEntry() {};
ReferenceEntry() = default;
ReferenceEntry( App::DocumentObject* docObject, std::string subName, App::Document* document = nullptr);
ReferenceEntry(const ReferenceEntry& other);
~ReferenceEntry() = default;
@@ -62,9 +63,9 @@ public:
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; }
void setSubName(const std::string& subName) { m_subName = subName; }
std::string getObjectName() const { return m_objectName; }
void setObjectName(std::string name) { m_objectName = name; }
void setObjectName(const std::string& name) { m_objectName = name; }
App::Document* getDocument() const { return m_document; }
void setDocument(App::Document* document) { m_document = document; }
@@ -73,17 +74,22 @@ public:
bool isWholeObject() const;
Part::TopoShape asTopoShape() const;
Part::TopoShape asCanonicalTopoShape() const;
static Part::TopoShape asCanonicalTopoShape(const Part::TopoShape& inShape, const DrawViewPart& dvp);
bool is3d() const;
bool hasGeometry() const;
private:
Part::TopoShape asTopoShapeVertex(TopoDS_Vertex &vert) const;
Part::TopoShape asTopoShapeEdge(TopoDS_Edge& edge) const;
bool hasGeometry2d() const;
TopoDS_Shape getGeometry2d() const;
static Part::TopoShape asTopoShapeVertex(const TopoDS_Vertex &vert);
static Part::TopoShape asTopoShapeEdge(const TopoDS_Edge& edge);
App::DocumentObject* m_object{nullptr};
std::string m_subName{""};
std::string m_objectName{""};
std::string m_subName;
std::string m_objectName;
App::Document* m_document{nullptr};
};

View File

@@ -1944,7 +1944,7 @@ void DrawUtil::dumpEdge(const char* label, int i, TopoDS_Edge e)
vEnd.Z(),
static_cast<int>(e.Orientation()));
double edgeLength = GCPnts_AbscissaPoint::Length(adapt, Precision::Confusion());
Base::Console().Message(">>>>>>> length: %.3f distance: %.3f ration: %.3f type: %d\n",
Base::Console().Message(">>>>>>> length: %.3f distance: %.3f ratio: %.3f type: %d\n",
edgeLength,
vStart.Distance(vEnd),
edgeLength / vStart.Distance(vEnd),

View File

@@ -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");
}

View File

@@ -128,7 +128,10 @@ public:
virtual bool haveTolerance();
virtual double getDimValue();
QStringList getPrefixSuffixSpec(QString fSpec);
virtual double getTrueDimValue() const;
virtual double getProjectedDimValue() const;
QStringList getPrefixSuffixSpec(const QString& fSpec);
virtual DrawViewPart* getViewPart() const;
QRectF getRect() const override
@@ -238,6 +241,7 @@ protected:
void updateSavedGeometry();
bool validateReferenceForm() const;
bool autocorrectReferences();
private:
static const char* TypeEnums[];

View File

@@ -96,14 +96,16 @@ using DU = DrawUtil;
PROPERTY_SOURCE_WITH_EXTENSIONS(TechDraw::DrawViewPart, TechDraw::DrawView)
DrawViewPart::DrawViewPart(void)
: geometryObject(nullptr), m_tempGeometryObject(nullptr), m_waitingForFaces(false),
DrawViewPart::DrawViewPart()
: geometryObject(nullptr),
m_tempGeometryObject(nullptr),
m_handleFaces(false),
nowUnsetting(false),
m_waitingForFaces(false),
m_waitingForHlr(false)
{
static const char* group = "Projection";
static const char* sgroup = "HLR Parameters";
nowUnsetting = false;
m_handleFaces = false;
CosmeticExtension::initExtension(this);
@@ -203,14 +205,14 @@ std::vector<App::DocumentObject*> DrawViewPart::getAllSources() const
//! pick vertex objects out of the Source properties and
//! add them directly to the geometry without going through HLR
void DrawViewPart::addPoints(void)
void DrawViewPart::addPoints()
{
// Base::Console().Message("DVP::addPoints()\n");
// get all the 2d shapes in the sources, then pick through them for vertices.
std::vector<TopoDS_Shape> shapes = ShapeExtractor::getShapes2d(getAllSources());
for (auto& s : shapes) {
if (s.ShapeType() == TopAbs_VERTEX) {
gp_Pnt gp = BRep_Tool::Pnt(TopoDS::Vertex(s));
std::vector<TopoDS_Shape> shapesAll = ShapeExtractor::getShapes2d(getAllSources());
for (auto& shape : shapesAll) {
if (shape.ShapeType() == TopAbs_VERTEX) {
gp_Pnt gp = BRep_Tool::Pnt(TopoDS::Vertex(shape));
Base::Vector3d vp(gp.X(), gp.Y(), gp.Z());
vp = vp - m_saveCentroid;
//need to offset the point to match the big projection
@@ -221,9 +223,9 @@ void DrawViewPart::addPoints(void)
}
}
App::DocumentObjectExecReturn* DrawViewPart::execute(void)
App::DocumentObjectExecReturn* DrawViewPart::execute()
{
// Base::Console().Message("DVP::execute() - %s\n", getNameInDocument());
// Base::Console().Message("DVP::execute() - %s\n", getNameInDocument());
if (!keepUpdated()) {
return DrawView::execute();
}
@@ -375,7 +377,7 @@ TechDraw::GeometryObjectPtr DrawViewPart::buildGeometryObject(TopoDS_Shape& shap
}
//! continue processing after hlr thread completes
void DrawViewPart::onHlrFinished(void)
void DrawViewPart::onHlrFinished()
{
// Base::Console().Message("DVP::onHlrFinished() - %s\n", getNameInDocument());
@@ -423,9 +425,9 @@ void DrawViewPart::onHlrFinished(void)
}
//! run any tasks that need to been done after geometry is available
void DrawViewPart::postHlrTasks(void)
void DrawViewPart::postHlrTasks()
{
// Base::Console().Message("DVP::postHlrTasks() - %s\n", getNameInDocument());
// Base::Console().Message("DVP::postHlrTasks() - %s\n", getNameInDocument());
//add geometry that doesn't come from HLR
addCosmeticVertexesToGeom();
addCosmeticEdgesToGeom();
@@ -434,15 +436,15 @@ void DrawViewPart::postHlrTasks(void)
//balloons need to be recomputed here because their
//references will be invalid until the geometry exists
std::vector<TechDraw::DrawViewBalloon*> bals = getBalloons();
for (auto& b : bals) {
b->recomputeFeature();
std::vector<TechDraw::DrawViewBalloon*> balloonsAll = getBalloons();
for (auto& balloon : balloonsAll) {
balloon->recomputeFeature();
}
// Dimensions need to be recomputed now if face finding is not going to take place.
if (!handleFaces() || CoarseView.getValue()) {
std::vector<TechDraw::DrawViewDimension*> dims = getDimensions();
for (auto& d : dims) {
d->recomputeFeature();
std::vector<TechDraw::DrawViewDimension*> dimsAll = getDimensions();
for (auto& dim : dimsAll) {
dim->recomputeFeature();
}
}
@@ -460,16 +462,17 @@ void DrawViewPart::postHlrTasks(void)
}
// Run any tasks that need to be done after faces are available
void DrawViewPart::postFaceExtractionTasks(void)
void DrawViewPart::postFaceExtractionTasks()
{
// Base::Console().Message("DVP::postFaceExtractionTasks() - %s\n", getNameInDocument());
// Some centerlines depend on faces so we could not add CL geometry before now
addCenterLinesToGeom();
// Dimensions need to be recomputed because their references will be invalid
// until all the geometry (including centerlines dependent on faces) exists.
std::vector<TechDraw::DrawViewDimension*> dims = getDimensions();
for (auto& d : dims) {
d->recomputeFeature();
std::vector<TechDraw::DrawViewDimension*> dimsAll = getDimensions();
for (auto& dim : dimsAll) {
dim->recomputeFeature();
}
requestPaint();
@@ -529,10 +532,10 @@ void DrawViewPart::findFacesNew(const std::vector<BaseGeomPtr> &goEdges)
geometryObject->clearFaceGeom();
std::vector<TopoDS_Wire> closedWires;
for (auto& e : closedEdges) {
BRepBuilderAPI_MakeWire mkWire(e);
TopoDS_Wire w = mkWire.Wire();
closedWires.push_back(w);
for (auto& edge : closedEdges) {
BRepBuilderAPI_MakeWire mkWire(edge);
TopoDS_Wire wire = mkWire.Wire();
closedWires.push_back(wire);
}
if (!closedWires.empty()) {
sortedWires.insert(sortedWires.end(), closedWires.begin(), closedWires.end());
@@ -548,7 +551,7 @@ void DrawViewPart::findFacesNew(const std::vector<BaseGeomPtr> &goEdges)
}
else {
constexpr double minWireArea = 0.000001;//arbitrary very small face size
std::vector<TopoDS_Wire>::iterator itWire = sortedWires.begin();
auto itWire = sortedWires.begin();
for (; itWire != sortedWires.end(); itWire++) {
if (!BRep_Tool::IsClosed(*itWire)) {
continue;//can not make a face from open wire
@@ -559,17 +562,18 @@ void DrawViewPart::findFacesNew(const std::vector<BaseGeomPtr> &goEdges)
continue;//can not make a face from wire with no area
}
TechDraw::FacePtr f(std::make_shared<TechDraw::Face>());
TechDraw::FacePtr face(std::make_shared<TechDraw::Face>());
const TopoDS_Wire& wire = (*itWire);
f->wires.push_back(new TechDraw::Wire(wire));
face->wires.push_back(new TechDraw::Wire(wire));
if (geometryObject) {
geometryObject->addFaceGeom(f);
geometryObject->addFaceGeom(face);
}
}
}
}
// original face finding method
// original face finding method. This is retained only to produce the same face geometry in older
// documents.
void DrawViewPart::findFacesOld(const std::vector<BaseGeomPtr> &goEdges)
{
//make a copy of the input edges so the loose tolerances of face finding are
@@ -685,7 +689,7 @@ void DrawViewPart::findFacesOld(const std::vector<BaseGeomPtr> &goEdges)
}
//continue processing after extractFaces thread completes
void DrawViewPart::onFacesFinished(void)
void DrawViewPart::onFacesFinished()
{
// Base::Console().Message("DVP::onFacesFinished() - %s\n", getNameInDocument());
waitingForFaces(false);
@@ -1025,24 +1029,15 @@ bool DrawViewPart::waitingForResult() const
return false;
}
bool DrawViewPart::hasGeometry(void) const
bool DrawViewPart::hasGeometry() const
{
if (!geometryObject) {
return false;
}
if (waitingForHlr()) {
return false;
}
const std::vector<TechDraw::VertexPtr>& verts = getVertexGeometry();
const std::vector<TechDraw::BaseGeomPtr>& edges = getEdgeGeometry();
if (verts.empty() && edges.empty()) {
return false;
}
else {
return true;
}
return false;
return !(verts.empty() && edges.empty());
}
//convert a vector in local XY coords into a coordinate system in global
@@ -1165,7 +1160,7 @@ bool DrawViewPart::handleFaces()
return Preferences::getPreferenceGroup("General")->GetBool("HandleFaces", true);
}
bool DrawViewPart::newFaceFinder(void)
bool DrawViewPart::newFaceFinder()
{
return Preferences::getPreferenceGroup("General")->GetBool("NewFaceFinder", false);
}
@@ -1442,6 +1437,7 @@ void DrawViewPart::removeReferenceVertex(std::string tag)
resetReferenceVerts();
}
//! remove reference vertexes from the view geometry
void DrawViewPart::removeAllReferencesFromGeom()
{
// Base::Console().Message("DVP::removeAllReferencesFromGeom()\n");

View File

@@ -146,7 +146,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);
Part::TopoShape asTopoShape(double scale = 1.0);
virtual double getStartAngle() { return 0.0; }
virtual double getEndAngle() { return 0.0; }
@@ -391,7 +391,7 @@ class TechDrawExport Vertex
bool isReference() { return m_reference; }
void isReference(bool state) { m_reference = state; }
Part::TopoShape asTopoShape(double scale);
Part::TopoShape asTopoShape(double scale = 1.0);
protected:
//Uniqueness

View File

@@ -52,22 +52,20 @@ using DU = DrawUtil;
// a set of routines for comparing geometry for equality.
bool GeometryMatcher::compareGeometry(Part::TopoShape shape1, Part::TopoShape shape2)
bool GeometryMatcher::compareGeometry(const Part::TopoShape &shape1, const Part::TopoShape &shape2)
{
// Base::Console().Message("GM::compareGeometry()\n");
// Base::Console().Message("GM::compareGeometry()\n");
if (!Preferences::useExactMatchOnDims()) {
return false;
}
if (shape1.isNull() || shape2.isNull()) {
// Base::Console().Message("GM::compareGeometry - one or more TopoShapes are
// null\n");
Base::Console().Message("GM::compareGeometry - at least 1 input shape is null (1)\n");
return false;
}
TopoDS_Shape geom1 = shape1.getShape();
TopoDS_Shape geom2 = shape2.getShape();
const TopoDS_Shape& geom1 = shape1.getShape();
const TopoDS_Shape& geom2 = shape2.getShape();
if (geom1.IsNull() || geom2.IsNull()) {
// Base::Console().Message("GM::compareGeometry - one or more TopoDS_Shapes are
// null\n");
Base::Console().Message("GM::compareGeometry - at least 1 input shape is null (2)\n");
return false;
}
@@ -80,10 +78,9 @@ bool GeometryMatcher::compareGeometry(Part::TopoShape shape1, Part::TopoShape sh
return false;
}
bool GeometryMatcher::comparePoints(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
bool GeometryMatcher::comparePoints(const TopoDS_Shape& shape1, const 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;
@@ -92,24 +89,18 @@ bool GeometryMatcher::comparePoints(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
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;
return point1.IsEqual(point2, EWTOLERANCE);
}
bool GeometryMatcher::compareEdges(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
bool GeometryMatcher::compareEdges(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2)
{
// Base::Console().Message("GM::compareEdges()\n");
// 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;
return false;
}
TopoDS_Edge edge1 = TopoDS::Edge(shape1);
TopoDS_Edge edge2 = TopoDS::Edge(shape2);
if (edge1.IsNull() || edge2.IsNull()) {
// Base::Console().Message("GM::compareEdges - an input edge is null\n");
return false;
}
@@ -124,18 +115,14 @@ bool GeometryMatcher::compareEdges(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
if (adapt1.IsClosed() && adapt2.IsClosed()) {
return compareCircles(edge1, edge2);
}
else {
return compareCircleArcs(edge1, edge2);
}
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);
}
return compareEllipseArcs(edge1, edge2);
}
if (adapt1.GetType() == GeomAbs_BSplineCurve && adapt2.GetType() == GeomAbs_BSplineCurve) {
@@ -146,9 +133,9 @@ bool GeometryMatcher::compareEdges(TopoDS_Shape& shape1, TopoDS_Shape& shape2)
return compareDifferent(edge1, edge2);
}
bool GeometryMatcher::compareLines(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareLines(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
// Base::Console().Message("GM::compareLines()\n");
// Base::Console().Message("GM::compareLines()\n");
// how does the edge that was NOT null in compareEdges become null here?
// should not happen, but does!
if (edge1.IsNull() || edge2.IsNull()) {
@@ -159,19 +146,14 @@ bool GeometryMatcher::compareLines(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
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;
return start1.IsEqual(start2, EWTOLERANCE) && end1.IsEqual(end2, EWTOLERANCE);
}
bool GeometryMatcher::compareCircles(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareCircles(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
// Base::Console().Message("GM::compareCircles()\n");
// how does the edge that was NOT null in compareEdges become null here?
if (edge1.IsNull() || edge2.IsNull()) {
// Base::Console().Message("GM::compareCircles - an input edge is null\n");
return false;
}
@@ -183,18 +165,13 @@ bool GeometryMatcher::compareCircles(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
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;
return DU::fpCompare(radius1, radius2, EWTOLERANCE) && center1.IsEqual(center2, EWTOLERANCE);
}
bool GeometryMatcher::compareEllipses(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareEllipses(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
// how does the edge that was NOT null in compareEdges become null here?
if (edge1.IsNull() || edge2.IsNull()) {
// Base::Console().Message("GM::compareEllipses - an input edge is null\n");
return false;
}
@@ -208,21 +185,17 @@ bool GeometryMatcher::compareEllipses(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
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;
return (DU::fpCompare(major1, major2, EWTOLERANCE) &&
DU::fpCompare(minor1, minor2, EWTOLERANCE) &&
center1.IsEqual(center2, EWTOLERANCE));
}
// for our purposes, only lines or circles masquerading as bsplines are of interest
bool GeometryMatcher::compareBSplines(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareBSplines(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
// Base::Console().Message("GM::compareBSplines()\n");
// how does the edge that was NOT null in compareEdges become null here?
if (edge1.IsNull() || edge2.IsNull()) {
Base::Console().Message("GM::compareBSplines - an input edge is null\n");
return false;
}
@@ -258,19 +231,19 @@ bool GeometryMatcher::compareBSplines(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
}
// this is a weak comparison. we should also check center & radius?
bool GeometryMatcher::compareCircleArcs(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareCircleArcs(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
return compareEndPoints(edge1, edge2);
}
bool GeometryMatcher::compareEllipseArcs(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareEllipseArcs(const TopoDS_Edge& edge1, const 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)
bool GeometryMatcher::compareDifferent(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
// Base::Console().Message("GM::compareDifferent()\n");
BRepAdaptor_Curve adapt1(edge1);
@@ -278,11 +251,10 @@ bool GeometryMatcher::compareDifferent(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
return false;
}
bool GeometryMatcher::compareEndPoints(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
bool GeometryMatcher::compareEndPoints(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2)
{
// how does the edge that was NOT null in compareEdges become null here?
if (edge1.IsNull() || edge2.IsNull()) {
// Base::Console().Message("GM::compareLine - an input edge is null\n");
return false;
}
@@ -301,9 +273,7 @@ bool GeometryMatcher::compareEndPoints(TopoDS_Edge& edge1, TopoDS_Edge& edge2)
props2.SetParameter(pLast2);
auto end2 = DU::toVector3d(props2.Value());
if (begin1.IsEqual(begin2, EWTOLERANCE) && end1.IsEqual(end2, EWTOLERANCE)) {
// exact match
return true;
}
return false;
return (begin1.IsEqual(begin2, EWTOLERANCE) &&
end1.IsEqual(end2, EWTOLERANCE));
}

View File

@@ -39,25 +39,12 @@ namespace TechDraw
class TechDrawExport GeometryMatcher
{
public:
GeometryMatcher()
{}
explicit GeometryMatcher(DrawViewDimension* dim)
{
m_dimension = dim;
}
~GeometryMatcher() = default;
GeometryMatcher() :
m_dimension(nullptr) {}
explicit GeometryMatcher(DrawViewDimension* dim) :
m_dimension(dim) {}
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);
bool compareGeometry(const Part::TopoShape& geom1, const Part::TopoShape& geom2);
double getPointTolerance() const
{
@@ -69,7 +56,18 @@ public:
}
private:
bool compareEndPoints(TopoDS_Edge& edge1, TopoDS_Edge& edge2);
static bool comparePoints(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2);
static bool compareEdges(const TopoDS_Shape& shape1, const TopoDS_Shape& shape2);
static bool compareLines(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareCircles(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareEllipses(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareBSplines(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareDifferent(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareCircleArcs(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareEllipseArcs(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
static bool compareEndPoints(const TopoDS_Edge& edge1, const TopoDS_Edge& edge2);
DrawViewDimension* m_dimension;
double m_pointTolerance {EWTOLERANCE};

View File

@@ -142,7 +142,6 @@ void GeometryObject::clear()
void GeometryObject::projectShape(const TopoDS_Shape& inShape, const gp_Ax2& viewAxis)
{
// Base::Console().Message("GO::projectShape()\n");
clear();
Handle(HLRBRep_Algo) brep_hlr;
@@ -286,21 +285,6 @@ void GeometryObject::makeTDGeometry()
}
}
//mirror a shape thru XZ plane for Qt's inverted Y coordinate
TopoDS_Shape ShapeUtils::invertGeometry(const TopoDS_Shape s)
{
if (s.IsNull()) {
return s;
}
gp_Trsf mirrorY;
gp_Pnt org(0.0, 0.0, 0.0);
gp_Dir Y(0.0, 1.0, 0.0);
gp_Ax2 mirrorPlane(org, Y);
mirrorY.SetMirror(mirrorPlane);
BRepBuilderAPI_Transform mkTrf(s, mirrorY, true);
return mkTrf.Shape();
}
//!set up a hidden line remover and project a shape with it
void GeometryObject::projectShapeWithPolygonAlgo(const TopoDS_Shape& input, const gp_Ax2& viewAxis)

View File

@@ -320,6 +320,48 @@ TopoDS_Shape ShapeUtils::moveShape(const TopoDS_Shape& input, const Base::Vector
return transShape;
}
//mirror a shape thru XZ plane for Qt's inverted Y coordinate
TopoDS_Shape ShapeUtils::invertGeometry(const TopoDS_Shape s)
{
if (s.IsNull()) {
return s;
}
gp_Trsf mirrorY;
gp_Pnt org(0.0, 0.0, 0.0);
gp_Dir Y(0.0, 1.0, 0.0);
gp_Ax2 mirrorPlane(org, Y);
mirrorY.SetMirror(mirrorPlane);
BRepBuilderAPI_Transform mkTrf(s, mirrorY, true);
return mkTrf.Shape();
}
//! transforms a shape defined in invertedY (Qt) coordinates into one defined by
//! conventional coordinates
TopoDS_Shape ShapeUtils::fromQt(const TopoDS_Shape& inShape)
{
gp_Ax3 OXYZ;
gp_Ax3 Qt;
Qt.YReverse();
gp_Trsf xFromQt;
xFromQt.SetTransformation(Qt, OXYZ);
BRepBuilderAPI_Transform mkTrf(inShape, xFromQt);
return mkTrf.Shape();
}
//! transforms a shape defined in conventional coordinates coordinates into one defined by
//! invertedY (Qt) coordinates
TopoDS_Shape ShapeUtils::toQt(const TopoDS_Shape& inShape)
{
gp_Ax3 OXYZ;
gp_Ax3 Qt;
Qt.YReverse();
gp_Trsf xFromQt;
xFromQt.SetTransformation(OXYZ, Qt);
BRepBuilderAPI_Transform mkTrf(inShape, xFromQt);
return mkTrf.Shape();
}
std::pair<Base::Vector3d, Base::Vector3d> ShapeUtils::getEdgeEnds(TopoDS_Edge edge)
{
std::pair<Base::Vector3d, Base::Vector3d> result;

View File

@@ -110,6 +110,9 @@ public:
static bool isShapeReallyNull(TopoDS_Shape shape);
static bool edgesAreParallel(TopoDS_Edge edge0, TopoDS_Edge edge1);
static TopoDS_Shape fromQt(const TopoDS_Shape& inShape);
static TopoDS_Shape toQt(const TopoDS_Shape& inShape);
};
}