Improve handling of duplicate edges in projection
This commit is contained in:
parent
3797f7ebc3
commit
1f0899ef3d
|
@ -124,8 +124,8 @@ std::vector<TopoDS_Edge> DrawProjectSplit::getEdgesForWalker(TopoDS_Shape shape,
|
|||
|
||||
|
||||
TechDrawGeometry::GeometryObject* DrawProjectSplit::buildGeometryObject(
|
||||
TopoDS_Shape shape,
|
||||
gp_Pnt& inputCenter,
|
||||
TopoDS_Shape shape,
|
||||
gp_Pnt& inputCenter,
|
||||
Base::Vector3d direction)
|
||||
{
|
||||
TechDrawGeometry::GeometryObject* geometryObject = new TechDrawGeometry::GeometryObject("DrawProjectSplit");
|
||||
|
@ -156,7 +156,7 @@ std::vector<TopoDS_Edge> DrawProjectSplit::getEdges(TechDrawGeometry::GeometryOb
|
|||
if (!DrawUtil::isZeroEdge(e)) {
|
||||
nonZero.push_back(e);
|
||||
} else {
|
||||
Base::Console().Message("INFO - DPS::extractFaces found ZeroEdge!\n");
|
||||
Base::Console().Message("INFO - DPS::getEdges found ZeroEdge!\n");
|
||||
}
|
||||
}
|
||||
faceEdges = nonZero;
|
||||
|
@ -230,6 +230,8 @@ std::vector<TopoDS_Edge> DrawProjectSplit::getEdges(TechDrawGeometry::GeometryOb
|
|||
if (newEdges.empty()) {
|
||||
Base::Console().Log("LOG - DPS::extractFaces - no newEdges\n");
|
||||
}
|
||||
newEdges = removeDuplicateEdges(newEdges);
|
||||
|
||||
return newEdges;
|
||||
}
|
||||
|
||||
|
@ -426,3 +428,103 @@ std::vector<splitPoint> DrawProjectSplit::sortSplits(std::vector<splitPoint>& s,
|
|||
}
|
||||
|
||||
|
||||
std::vector<TopoDS_Edge> DrawProjectSplit::removeDuplicateEdges(std::vector<TopoDS_Edge>& inEdges)
|
||||
{
|
||||
std::vector<TopoDS_Edge> result;
|
||||
std::vector<edgeSortItem> temp;
|
||||
|
||||
unsigned int idx = 0;
|
||||
for (auto& e: inEdges) {
|
||||
edgeSortItem item;
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
item.start = DrawUtil::vertex2Vector(v1);
|
||||
item.end = DrawUtil::vertex2Vector(v2);
|
||||
item.startAngle = DrawUtil::angleWithX(e,v1);
|
||||
item.endAngle = DrawUtil::angleWithX(e,v2);
|
||||
//catch reverse-duplicates
|
||||
if (DrawUtil::vectorCompare(item.start,item.end) > 0) {
|
||||
Base::Vector3d vTemp = item.start;
|
||||
item.start = item.end;
|
||||
item.end = vTemp;
|
||||
double aTemp = item.startAngle;
|
||||
item.startAngle = item.endAngle;
|
||||
item.endAngle = aTemp;
|
||||
}
|
||||
item.idx = idx;
|
||||
temp.push_back(item);
|
||||
idx++;
|
||||
}
|
||||
|
||||
std::vector<edgeSortItem> sorted = sortEdges(temp,true);
|
||||
auto last = std::unique(sorted.begin(), sorted.end(), edgeSortItem::edgeEqual); //duplicates to back
|
||||
sorted.erase(last, sorted.end()); //remove dupls
|
||||
|
||||
for (auto& e: sorted) {
|
||||
result.push_back(inEdges.at(e.idx));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<edgeSortItem> DrawProjectSplit::sortEdges(std::vector<edgeSortItem>& e, bool ascend)
|
||||
{
|
||||
std::vector<edgeSortItem> sorted = e;
|
||||
std::sort(sorted.begin(), sorted.end(), edgeSortItem::edgeCompare);
|
||||
if (ascend) {
|
||||
std::reverse(sorted.begin(),sorted.end());
|
||||
}
|
||||
return sorted;
|
||||
}
|
||||
|
||||
|
||||
//*************************
|
||||
//* edgeSortItem Methods
|
||||
//*************************
|
||||
std::string edgeSortItem::dump(void)
|
||||
{
|
||||
std::string result;
|
||||
std::stringstream builder;
|
||||
builder << "edgeSortItem - s: " << DrawUtil::formatVector(start) << " e: " << DrawUtil::formatVector(end) <<
|
||||
" sa: " << startAngle * 180.0/M_PI << " ea: " << endAngle* 180.0/M_PI << " idx: " << idx;
|
||||
result = builder.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//true if "e1 < e2" - for sorting
|
||||
/*static*/bool edgeSortItem::edgeCompare(const edgeSortItem& e1, const edgeSortItem& e2)
|
||||
{
|
||||
bool result = false;
|
||||
int vCompare = DrawUtil::vectorCompare(e1.start, e2.start);
|
||||
if ( vCompare == -1) {
|
||||
result = true;
|
||||
} else if (vCompare == 0) {
|
||||
if (e1.startAngle < e2.startAngle) {
|
||||
result = true;
|
||||
} else if (DrawUtil::fpCompare(e1.startAngle, e2.startAngle)) {
|
||||
if (e1.endAngle < e2.startAngle) {
|
||||
result = true;
|
||||
} else if (DrawUtil::fpCompare(e1.endAngle, e2.endAngle)) {
|
||||
if (e1.idx < e2.idx) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//true if "e1 = e2" - for sorting/unique test
|
||||
/*static*/bool edgeSortItem::edgeEqual(const edgeSortItem& e1, const edgeSortItem& e2)
|
||||
{
|
||||
bool result = false;
|
||||
if ( (e1.start == e2.start) &&
|
||||
(e1.end == e2.end) &&
|
||||
(DrawUtil::fpCompare(e1.startAngle,e2.startAngle)) &&
|
||||
(DrawUtil::fpCompare(e1.endAngle,e2.endAngle)) ) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
//
|
||||
|
|
|
@ -46,12 +46,31 @@ class BaseGeom;
|
|||
|
||||
namespace TechDraw
|
||||
{
|
||||
struct splitPoint {
|
||||
struct splitPoint
|
||||
{
|
||||
int i;
|
||||
Base::Vector3d v;
|
||||
double param;
|
||||
};
|
||||
|
||||
class edgeSortItem
|
||||
{
|
||||
public:
|
||||
edgeSortItem() {}
|
||||
~edgeSortItem() {}
|
||||
|
||||
Base::Vector3d start;
|
||||
Base::Vector3d end;
|
||||
double startAngle;
|
||||
double endAngle;
|
||||
unsigned int idx;
|
||||
|
||||
static bool edgeCompare(const edgeSortItem& e1, const edgeSortItem& e2);
|
||||
static bool edgeEqual(const edgeSortItem& e1, const edgeSortItem& e2);
|
||||
std::string dump(void);
|
||||
};
|
||||
|
||||
|
||||
class TechDrawExport DrawProjectSplit
|
||||
{
|
||||
public:
|
||||
|
@ -65,12 +84,16 @@ public:
|
|||
static bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds = false);
|
||||
static std::vector<TopoDS_Edge> splitEdges(std::vector<TopoDS_Edge> orig, std::vector<splitPoint> splits);
|
||||
static std::vector<TopoDS_Edge> split1Edge(TopoDS_Edge e, std::vector<splitPoint> splitPoints);
|
||||
static double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2); //const; //probably sb static or DrawUtil
|
||||
static double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2);
|
||||
|
||||
static std::vector<splitPoint> sortSplits(std::vector<splitPoint>& s, bool ascend);
|
||||
static bool splitCompare(const splitPoint& p1, const splitPoint& p2);
|
||||
static bool splitEqual(const splitPoint& p1, const splitPoint& p2);
|
||||
|
||||
static std::vector<TopoDS_Edge> removeDuplicateEdges(std::vector<TopoDS_Edge>& inEdges);
|
||||
static std::vector<edgeSortItem> sortEdges(std::vector<edgeSortItem>& e, bool ascend);
|
||||
|
||||
|
||||
protected:
|
||||
static std::vector<TopoDS_Edge> getEdges(TechDrawGeometry::GeometryObject* geometryObject);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
# include <sstream>
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
#include <cmath>
|
||||
# include <exception>
|
||||
# include <boost/regex.hpp>
|
||||
# include <QString>
|
||||
|
@ -155,6 +156,10 @@ double DrawUtil::angleWithX(TopoDS_Edge e, bool reverse)
|
|||
u = end - start;
|
||||
}
|
||||
result = atan2(u.y,u.x);
|
||||
if (result < 0) {
|
||||
result += 2.0 * M_PI;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -200,6 +205,9 @@ double DrawUtil::angleWithX(TopoDS_Edge e, TopoDS_Vertex v)
|
|||
}
|
||||
}
|
||||
result = atan2(uVec.y,uVec.x);
|
||||
if (result < 0) { //map from [-PI:PI] to [0:2PI]
|
||||
result += 2.0 * M_PI;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -224,6 +232,59 @@ bool DrawUtil::isLastVert(TopoDS_Edge e, TopoDS_Vertex v)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool DrawUtil::fpCompare(const double& d1, const double& d2)
|
||||
{
|
||||
bool result = false;
|
||||
if (std::fabs(d1 - d2) < FLT_EPSILON) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Base::Vector3d DrawUtil::vertex2Vector(const TopoDS_Vertex& v)
|
||||
{
|
||||
gp_Pnt gp = BRep_Tool::Pnt(v);
|
||||
Base::Vector3d result(gp.X(),gp.Y(),gp.Z());
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string DrawUtil::formatVector(const Base::Vector3d& v)
|
||||
{
|
||||
std::string result;
|
||||
std::stringstream builder;
|
||||
builder << " (" << v.x << "," << v.y << "," << v.z << ") ";
|
||||
result = builder.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
//! compare 2 vectors for sorting purposes ( -1 -> v1<v2, 0 -> v1 == v2, 1 -> v1 > v2)
|
||||
int DrawUtil::vectorCompare(const Base::Vector3d& v1, const Base::Vector3d& v2)
|
||||
{
|
||||
int result = 0;
|
||||
if (v1 == v2) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (v1.x < v2.x) {
|
||||
result = -1;
|
||||
} else if (DrawUtil::fpCompare(v1.x, v2.x)) {
|
||||
if (v1.y < v2.y) {
|
||||
result = -1;
|
||||
} else if (DrawUtil::fpCompare(v1.y, v2.y)) {
|
||||
if (v1.z < v2.z) {
|
||||
result = -1;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
} else {
|
||||
result = 1; //v2y > v1y
|
||||
}
|
||||
} else {
|
||||
result = 1; //v1x > v2x
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//based on Function provided by Joe Dowsett, 2014
|
||||
double DrawUtil::sensibleScale(double working_scale)
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
||||
|
@ -50,6 +52,11 @@ class TechDrawExport DrawUtil {
|
|||
static double angleWithX(TopoDS_Edge e, TopoDS_Vertex v);
|
||||
static bool isFirstVert(TopoDS_Edge e, TopoDS_Vertex v);
|
||||
static bool isLastVert(TopoDS_Edge e, TopoDS_Vertex v);
|
||||
static bool fpCompare(const double& d1, const double& d2);
|
||||
static Base::Vector3d vertex2Vector(const TopoDS_Vertex& v);
|
||||
static std::string formatVector(const Base::Vector3d& v);
|
||||
static int vectorCompare(const Base::Vector3d& v1, const Base::Vector3d& v2);
|
||||
|
||||
|
||||
//debugging routines
|
||||
static void dumpVertexes(const char* text, const TopoDS_Shape& s);
|
||||
|
|
|
@ -266,7 +266,7 @@ TechDrawGeometry::GeometryObject* DrawViewPart::buildGeometryObject(TopoDS_Shape
|
|||
void DrawViewPart::extractFaces()
|
||||
{
|
||||
geometryObject->clearFaceGeom();
|
||||
const std::vector<TechDrawGeometry::BaseGeom*>& goEdges =
|
||||
const std::vector<TechDrawGeometry::BaseGeom*>& goEdges =
|
||||
geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue());
|
||||
std::vector<TechDrawGeometry::BaseGeom*>::const_iterator itEdge = goEdges.begin();
|
||||
std::vector<TopoDS_Edge> origEdges;
|
||||
|
@ -349,7 +349,7 @@ void DrawViewPart::extractFaces()
|
|||
|
||||
std::vector<splitPoint> sorted = DrawProjectSplit::sortSplits(splits,true);
|
||||
auto last = std::unique(sorted.begin(), sorted.end(), DrawProjectSplit::splitEqual); //duplicates to back
|
||||
sorted.erase(last, sorted.end()); //remove dupls
|
||||
sorted.erase(last, sorted.end()); //remove dupl splits
|
||||
std::vector<TopoDS_Edge> newEdges = DrawProjectSplit::splitEdges(faceEdges,sorted);
|
||||
|
||||
if (newEdges.empty()) {
|
||||
|
@ -357,6 +357,8 @@ void DrawViewPart::extractFaces()
|
|||
return;
|
||||
}
|
||||
|
||||
newEdges = DrawProjectSplit::removeDuplicateEdges(newEdges);
|
||||
|
||||
//find all the wires in the pile of faceEdges
|
||||
EdgeWalker ew;
|
||||
ew.loadEdges(newEdges);
|
||||
|
|
|
@ -536,6 +536,14 @@ bool WalkerEdge::isEqual(WalkerEdge w)
|
|||
return (i.idx < j.idx);
|
||||
}
|
||||
|
||||
std::string WalkerEdge::dump(void)
|
||||
{
|
||||
std::string result;
|
||||
std::stringstream builder;
|
||||
builder << "WalkerEdge - v1: " << v1 << " v2: " << v2 << " idx: " << idx << " ed: " << ed;
|
||||
result = builder.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
//*****************************************
|
||||
// ewWire Methods
|
||||
|
@ -615,24 +623,37 @@ std::string embedItem::dump(void)
|
|||
std::stringstream builder;
|
||||
builder << "embedItem - vertex: " << iVertex << " incidenceList: ";
|
||||
for (auto& ii : incidenceList) {
|
||||
builder << "e:" << ii.iEdge << "/a:" << (ii.angle * (180.0/M_PI)) << "/ed: " << ii.eDesc;
|
||||
builder << " e:" << ii.iEdge << "/a:" << (ii.angle * (180.0/M_PI)) << "/ed:" << ii.eDesc;
|
||||
}
|
||||
result = builder.str();
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ bool embedItem::iiCompare(incidenceItem i1, incidenceItem i2)
|
||||
{
|
||||
return (i1.angle > i2.angle);
|
||||
}
|
||||
|
||||
std::vector<incidenceItem> embedItem::sortIncidenceList (std::vector<incidenceItem> &list, bool ascend)
|
||||
{
|
||||
//Base::Console().Message("TRACE - eI::sortIncidenceList()\n");
|
||||
std::vector< incidenceItem > tempList = list;
|
||||
std::sort(tempList.begin(), tempList.end(), embedItem::iiCompare);
|
||||
std::sort(tempList.begin(), tempList.end(), incidenceItem::iiCompare);
|
||||
if (ascend) {
|
||||
std::reverse(tempList.begin(),tempList.end());
|
||||
}
|
||||
return tempList;
|
||||
}
|
||||
|
||||
//*************************************
|
||||
//* incidenceItem Methods
|
||||
//*************************************
|
||||
|
||||
/*static*/ bool incidenceItem::iiCompare(const incidenceItem& i1, const incidenceItem& i2)
|
||||
{
|
||||
return (i1.angle > i2.angle);
|
||||
}
|
||||
|
||||
/*static*/bool incidenceItem::iiEqual(const incidenceItem& i1, const incidenceItem& i2)
|
||||
{
|
||||
//TODO: this should compare edges also but eDesc comparision is by address
|
||||
bool result = false;
|
||||
if (i1.angle == i2.angle) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ class WalkerEdge
|
|||
public:
|
||||
static bool weCompare(WalkerEdge i, WalkerEdge j);
|
||||
bool isEqual(WalkerEdge w);
|
||||
std::string dump(void);
|
||||
|
||||
std::size_t v1;
|
||||
std::size_t v2;
|
||||
|
@ -131,7 +132,8 @@ public:
|
|||
incidenceItem() {}
|
||||
incidenceItem(int idx, double a, edge_t ed) {iEdge = idx; angle = a; eDesc = ed;}
|
||||
~incidenceItem() {}
|
||||
|
||||
static bool iiCompare(const incidenceItem& i1, const incidenceItem& i2);
|
||||
static bool iiEqual(const incidenceItem& i1, const incidenceItem& i2);
|
||||
int iEdge;
|
||||
double angle;
|
||||
edge_t eDesc;
|
||||
|
@ -149,7 +151,6 @@ public:
|
|||
std::vector<incidenceItem> incidenceList;
|
||||
std::string dump(void);
|
||||
static std::vector<incidenceItem> sortIncidenceList (std::vector<incidenceItem> &list, bool ascend);
|
||||
static bool iiCompare(incidenceItem i1, incidenceItem i2);
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user