[TD]fix dimension autocorrect
- autocorrect was not handling scaled and rotated reference geometry properly.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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};
|
||||
};
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user