Performance Ph2
This commit is contained in:
parent
3cf036de4c
commit
001bbf52d6
|
@ -44,6 +44,8 @@
|
|||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -118,11 +120,21 @@ bool DrawUtil::isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool DrawUtil::isZeroEdge(TopoDS_Edge& e)
|
||||
bool DrawUtil::isZeroEdge(TopoDS_Edge e)
|
||||
{
|
||||
TopoDS_Vertex vStart = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex vEnd = TopExp::LastVertex(e);
|
||||
return isSamePoint(vStart,vEnd);
|
||||
bool result = isSamePoint(vStart,vEnd);
|
||||
if (result) {
|
||||
//closed edge will have same V's but non-zero length
|
||||
GProp_GProps props;
|
||||
BRepGProp::LinearProperties(e, props);
|
||||
double len = props.Mass();
|
||||
if (len > Precision::Confusion()) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//============================
|
||||
|
|
|
@ -41,7 +41,7 @@ class TechDrawExport DrawUtil {
|
|||
static std::string getGeomTypeFromName(std::string geomName);
|
||||
static std::string makeGeomName(std::string geomType, int index);
|
||||
static bool isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2);
|
||||
static bool isZeroEdge(TopoDS_Edge& e);
|
||||
static bool isZeroEdge(TopoDS_Edge e);
|
||||
//debugging routines
|
||||
static void dumpVertexes(const char* text, const TopoDS_Shape& s);
|
||||
static void dumpEdge(char* label, int i, TopoDS_Edge e);
|
||||
|
|
|
@ -134,7 +134,7 @@ short DrawView::mustExecute() const
|
|||
if (result) {
|
||||
return result;
|
||||
}
|
||||
return App::DocumentObject::mustExecute(); return App::DocumentObject::mustExecute();
|
||||
return App::DocumentObject::mustExecute();
|
||||
}
|
||||
|
||||
////you must override this in derived class
|
||||
|
@ -146,7 +146,6 @@ QRectF DrawView::getRect() const
|
|||
|
||||
void DrawView::onDocumentRestored()
|
||||
{
|
||||
// Rebuild the view
|
||||
DrawView::execute();
|
||||
}
|
||||
|
||||
|
|
|
@ -63,8 +63,10 @@
|
|||
|
||||
#endif
|
||||
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <GeomLib_Tool.hxx>
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Base/BoundBox.h>
|
||||
|
@ -128,10 +130,9 @@ DrawViewPart::DrawViewPart(void) : geometryObject(0)
|
|||
ADD_PROPERTY_TYPE(ArrowUpSection ,(false) ,lgroup,App::Prop_None,"Section line arrows point up");
|
||||
ADD_PROPERTY_TYPE(SymbolSection,("A") ,lgroup,App::Prop_None,"Section identifier");
|
||||
|
||||
geometryObject = new TechDrawGeometry::GeometryObject();
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/RunControl");
|
||||
m_interAlgo = hGrp->GetInt("InterAlgo", 2l);
|
||||
geometryObject = new TechDrawGeometry::GeometryObject(this);
|
||||
getRunControl();
|
||||
|
||||
}
|
||||
|
||||
DrawViewPart::~DrawViewPart()
|
||||
|
@ -197,13 +198,15 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
|
|||
}
|
||||
|
||||
#if MOD_TECHDRAW_HANDLE_FACES
|
||||
try {
|
||||
extractFaces();
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e4 = Standard_Failure::Caught();
|
||||
Base::Console().Log("LOG - DVP::execute - extractFaces failed for %s - %s **\n",getNameInDocument(),e4->GetMessageString());
|
||||
return new App::DocumentObjectExecReturn(e4->GetMessageString());
|
||||
if (handleFaces()) {
|
||||
try {
|
||||
extractFaces();
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e4 = Standard_Failure::Caught();
|
||||
Base::Console().Log("LOG - DVP::execute - extractFaces failed for %s - %s **\n",getNameInDocument(),e4->GetMessageString());
|
||||
return new App::DocumentObjectExecReturn(e4->GetMessageString());
|
||||
}
|
||||
}
|
||||
#endif //#if MOD_TECHDRAW_HANDLE_FACES
|
||||
|
||||
|
@ -272,7 +275,7 @@ void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter)
|
|||
void DrawViewPart::extractFaces()
|
||||
{
|
||||
geometryObject->clearFaceGeom();
|
||||
const std::vector<TechDrawGeometry::BaseGeom*>& goEdges = geometryObject->getEdgeGeometry();
|
||||
const std::vector<TechDrawGeometry::BaseGeom*>& goEdges = geometryObject->getEdgeGeometry(); //TODO: get visible edge geom!
|
||||
std::vector<TechDrawGeometry::BaseGeom*>::const_iterator itEdge = goEdges.begin();
|
||||
std::vector<TopoDS_Edge> origEdges;
|
||||
for (;itEdge != goEdges.end(); itEdge++) {
|
||||
|
@ -291,72 +294,79 @@ void DrawViewPart::extractFaces()
|
|||
faceEdges = nonZero;
|
||||
origEdges = nonZero;
|
||||
|
||||
std::vector<TopoDS_Edge>::iterator itOrig = origEdges.begin();
|
||||
|
||||
//HLR algo does not provide all edge intersections for edge endpoints.
|
||||
//need to split long edges touched by Vertex of another edge
|
||||
int idb = 0;
|
||||
for (; itOrig != origEdges.end(); itOrig++, idb++) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex((*itOrig));
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex((*itOrig));
|
||||
if (DrawUtil::isSamePoint(v1,v2)) {
|
||||
std::vector<splitPoint> splits;
|
||||
std::vector<TopoDS_Edge>::iterator itOuter = origEdges.begin();
|
||||
int iOuter = 0;
|
||||
for (; itOuter != origEdges.end(); itOuter++, iOuter++) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex((*itOuter));
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex((*itOuter));
|
||||
Bnd_Box sOuter;
|
||||
BRepBndLib::Add(*itOuter, sOuter);
|
||||
sOuter.SetGap(0.1);
|
||||
if (sOuter.IsVoid()) {
|
||||
Base::Console().Message("DVP::Extract Faces - outer Bnd_Box is void for %s\n",getNameInDocument());
|
||||
continue;
|
||||
}
|
||||
if (DrawUtil::isZeroEdge(*itOuter)) {
|
||||
Base::Console().Message("DVP::extractFaces - outerEdge: %d is ZeroEdge\n",iOuter); //this is not finding ZeroEdges
|
||||
continue; //skip zero length edges. shouldn't happen ;)
|
||||
}
|
||||
std::vector<TopoDS_Edge>::iterator itNew = faceEdges.begin();
|
||||
std::vector<size_t> deleteList;
|
||||
std::vector<TopoDS_Edge> edgesToAdd;
|
||||
int idx = 0;
|
||||
for (; itNew != faceEdges.end(); itNew++,idx++) {
|
||||
if ( itOrig->IsSame(*itNew) ){
|
||||
int iInner = 0;
|
||||
std::vector<TopoDS_Edge>::iterator itInner = faceEdges.begin();
|
||||
for (; itInner != faceEdges.end(); itInner++,iInner++) {
|
||||
if (iInner == iOuter) {
|
||||
continue;
|
||||
}
|
||||
if (DrawUtil::isZeroEdge((*itNew))) {
|
||||
if (DrawUtil::isZeroEdge((*itInner))) {
|
||||
continue; //skip zero length edges. shouldn't happen ;)
|
||||
}
|
||||
|
||||
bool removeThis = false;
|
||||
std::vector<TopoDS_Vertex> splitPoints;
|
||||
if (isOnEdge((*itNew),v1,false)) {
|
||||
splitPoints.push_back(v1);
|
||||
removeThis = true;
|
||||
Bnd_Box sInner;
|
||||
BRepBndLib::Add(*itInner, sInner);
|
||||
sInner.SetGap(0.1);
|
||||
if (sInner.IsVoid()) {
|
||||
Base::Console().Message("DVP::Extract Faces - inner Bnd_Box is void for %s\n",getNameInDocument());
|
||||
continue;
|
||||
}
|
||||
if (isOnEdge((*itNew),v2,false)) {
|
||||
splitPoints.push_back(v2);
|
||||
removeThis = true;
|
||||
}
|
||||
if (removeThis) {
|
||||
deleteList.push_back(idx);
|
||||
if (sOuter.IsOut(sInner)) { //bboxes of edges don't intersect, don't bother
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!splitPoints.empty()) {
|
||||
if (!DrawUtil::isZeroEdge((*itNew))) {
|
||||
std::vector<TopoDS_Edge> subEdges = splitEdge(splitPoints,(*itNew));
|
||||
edgesToAdd.insert(std::end(edgesToAdd), std::begin(subEdges), std::end(subEdges));
|
||||
}
|
||||
double param = -1;
|
||||
if (isOnEdge((*itInner),v1,param,false)) {
|
||||
gp_Pnt pnt1 = BRep_Tool::Pnt(v1);
|
||||
splitPoint s1;
|
||||
s1.i = iInner;
|
||||
s1.v = Base::Vector3d(pnt1.X(),pnt1.Y(),pnt1.Z());
|
||||
s1.param = param;
|
||||
splits.push_back(s1);
|
||||
}
|
||||
}
|
||||
//delete the split edge(s) and add the subedges
|
||||
//TODO: look into sets or maps or???? for all this
|
||||
std::sort(deleteList.begin(),deleteList.end()); //ascending
|
||||
auto last = std::unique(deleteList.begin(), deleteList.end()); //duplicates at back
|
||||
deleteList.erase(last, deleteList.end()); //remove dupls
|
||||
std::vector<size_t>::reverse_iterator ritDel = deleteList.rbegin();
|
||||
for ( ; ritDel != deleteList.rend(); ritDel++) {
|
||||
faceEdges.erase(faceEdges.begin() + (*ritDel));
|
||||
}
|
||||
faceEdges.insert(std::end(faceEdges), std::begin(edgesToAdd),std::end(edgesToAdd));
|
||||
}
|
||||
if (isOnEdge((*itInner),v2,param,false)) {
|
||||
gp_Pnt pnt2 = BRep_Tool::Pnt(v2);
|
||||
splitPoint s2;
|
||||
s2.i = iInner;
|
||||
s2.v = Base::Vector3d(pnt2.X(),pnt2.Y(),pnt2.Z());
|
||||
s2.param = param;
|
||||
splits.push_back(s2);
|
||||
}
|
||||
} //inner loop
|
||||
} //outer loop
|
||||
|
||||
std::vector<splitPoint> sorted = sortSplits(splits,true);
|
||||
auto last = std::unique(sorted.begin(), sorted.end(), DrawViewPart::splitEqual); //duplicates to back
|
||||
sorted.erase(last, sorted.end()); //remove dupls
|
||||
std::vector<TopoDS_Edge> newEdges = splitEdges(faceEdges,sorted);
|
||||
|
||||
if (faceEdges.empty()) {
|
||||
Base::Console().Log("LOG - DVP::extractFaces - no faceEdges\n");
|
||||
if (newEdges.empty()) {
|
||||
Base::Console().Log("LOG - DVP::extractFaces - no newEdges\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//find all the wires in the pile of faceEdges
|
||||
EdgeWalker ew;
|
||||
ew.loadEdges(faceEdges);
|
||||
ew.loadEdges(newEdges);
|
||||
bool success = ew.perform();
|
||||
if (!success) {
|
||||
Base::Console().Warning("DVP::extractFaces - input is not planar graph. No face detection\n");
|
||||
|
@ -377,7 +387,7 @@ void DrawViewPart::extractFaces()
|
|||
}
|
||||
}
|
||||
|
||||
double DrawViewPart::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) const
|
||||
double DrawViewPart::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2)
|
||||
{
|
||||
Standard_Real minDist = -1;
|
||||
|
||||
|
@ -396,126 +406,225 @@ double DrawViewPart::simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) const
|
|||
}
|
||||
|
||||
//this routine is the big time consumer. gets called many times (and is slow?))
|
||||
bool DrawViewPart::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, bool allowEnds)
|
||||
//note param gets modified here
|
||||
bool DrawViewPart::isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds)
|
||||
{
|
||||
bool result = false;
|
||||
bool outOfBox = false;
|
||||
param = -2;
|
||||
|
||||
//0) using parameterOnEdge
|
||||
if (m_interAlgo == 0) {
|
||||
try { //v. fast,but misses some edge/faces?? faster w/o bndbox check
|
||||
Standard_Real par = BRep_Tool::Parameter(v, e); //if this doesn't throw except then v is on e
|
||||
result = true;
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
double first = BRepLProp_CurveTool::FirstParameter(adapt);
|
||||
double last = BRepLProp_CurveTool::LastParameter(adapt);
|
||||
if ((fabs(par - first) < Precision::Confusion()) ||
|
||||
(fabs(par - last) < Precision::Confusion())) {
|
||||
if (!allowEnds) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught(); //"no parameter on Edge"
|
||||
}
|
||||
//eliminate obvious cases
|
||||
Bnd_Box sBox;
|
||||
BRepBndLib::Add(e, sBox);
|
||||
sBox.SetGap(0.1);
|
||||
if (sBox.IsVoid()) {
|
||||
Base::Console().Message("DVP::isOnEdge - Bnd_Box is void for %s\n",getNameInDocument());
|
||||
} else {
|
||||
//eliminate obvious cases
|
||||
Bnd_Box sBox;
|
||||
BRepBndLib::Add(e, sBox);
|
||||
sBox.SetGap(0.1);
|
||||
if (sBox.IsVoid()) {
|
||||
Base::Console().Message("DVP::isOnEdge - Bnd_Box is void for %s\n",getNameInDocument());
|
||||
} else {
|
||||
gp_Pnt pt = BRep_Tool::Pnt(v);
|
||||
if (sBox.IsOut(pt)) {
|
||||
outOfBox = true;
|
||||
}
|
||||
gp_Pnt pt = BRep_Tool::Pnt(v);
|
||||
if (sBox.IsOut(pt)) {
|
||||
outOfBox = true;
|
||||
}
|
||||
if (!outOfBox) {
|
||||
if (m_interAlgo == 1) {
|
||||
//1) using projPointOnCurve. roughly similar to dist to shape w/ bndbox. hangs(?) w/o bndbox
|
||||
try {
|
||||
gp_Pnt pt = BRep_Tool::Pnt(v);
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
Handle_Geom_Curve c = adapt.Curve().Curve();
|
||||
GeomAPI_ProjectPointOnCurve proj(pt,c);
|
||||
int n = proj.NbPoints();
|
||||
if (n > 0) {
|
||||
if (proj.LowerDistance() < Precision::Confusion()) {
|
||||
result = true;
|
||||
}
|
||||
double par = proj.LowerDistanceParameter();
|
||||
double first = BRepLProp_CurveTool::FirstParameter(adapt);
|
||||
double last = BRepLProp_CurveTool::LastParameter(adapt);
|
||||
if ((fabs(par - first) < Precision::Confusion()) ||
|
||||
(fabs(par - last) < Precision::Confusion())) {
|
||||
}
|
||||
if (!outOfBox) {
|
||||
if (m_interAlgo == 1) {
|
||||
//1) using projPointOnCurve. roughly similar to dist to shape w/ bndbox. hangs(?) w/o bndbox
|
||||
try {
|
||||
gp_Pnt pt = BRep_Tool::Pnt(v);
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
Handle_Geom_Curve c = adapt.Curve().Curve();
|
||||
GeomAPI_ProjectPointOnCurve proj(pt,c);
|
||||
int n = proj.NbPoints();
|
||||
if (n > 0) {
|
||||
if (proj.LowerDistance() < Precision::Confusion()) {
|
||||
param = proj.LowerDistanceParameter();
|
||||
result = true;
|
||||
}
|
||||
if (result) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) {
|
||||
if (!allowEnds) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught(); //no perp projection
|
||||
}
|
||||
} else if (m_interAlgo == 2) { //this is the original and still best algorithm
|
||||
double dist = simpleMinDist(v,e);
|
||||
if (dist < 0.0) {
|
||||
Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist);
|
||||
result = false;
|
||||
} else if (dist < Precision::Confusion()) {
|
||||
result = true;
|
||||
}
|
||||
if (result) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) {
|
||||
if (!allowEnds) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught(); //no perp projection
|
||||
}
|
||||
} else if (m_interAlgo == 2) { //can't provide param as is
|
||||
double dist = simpleMinDist(v,e);
|
||||
if (dist < 0.0) {
|
||||
Base::Console().Error("DVP::isOnEdge - simpleMinDist failed: %.3f\n",dist);
|
||||
result = false;
|
||||
} else if (dist < Precision::Confusion()) {
|
||||
const gp_Pnt pt = BRep_Tool::Pnt(v); //have to duplicate method 3 to get param
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
const Handle_Geom_Curve c = adapt.Curve().Curve();
|
||||
double maxDist = 0.000001; //magic number. less than this gives false positives.
|
||||
//bool found =
|
||||
(void) GeomLib_Tool::Parameter(c,pt,maxDist,param); //already know point it on curve
|
||||
result = true;
|
||||
}
|
||||
if (result) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) {
|
||||
if (!allowEnds) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
} //method 2
|
||||
} //!outofbox
|
||||
}
|
||||
} else if (m_interAlgo == 3) {
|
||||
const gp_Pnt pt = BRep_Tool::Pnt(v);
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
const Handle_Geom_Curve c = adapt.Curve().Curve();
|
||||
double par = -1;
|
||||
double maxDist = 0.000001; //magic number. less than this gives false positives.
|
||||
bool found = GeomLib_Tool::Parameter(c,pt,maxDist,par);
|
||||
if (found) {
|
||||
result = true;
|
||||
param = par;
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
if (DrawUtil::isSamePoint(v,v1) || DrawUtil::isSamePoint(v,v2)) {
|
||||
if (!allowEnds) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} //!outofbox
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Edge> DrawViewPart::splitEdges(std::vector<TopoDS_Edge> edges, std::vector<splitPoint> splits)
|
||||
{
|
||||
std::vector<TopoDS_Edge> result;
|
||||
std::vector<TopoDS_Edge> newEdges;
|
||||
std::vector<splitPoint> edgeSplits; //splits for current edge
|
||||
int iEdge = 0; //current edge index
|
||||
int iSplit = 0; //current splitindex
|
||||
int ii = 0; //i value of current split
|
||||
int endEdge = edges.size();
|
||||
int endSplit = splits.size();
|
||||
int imax = std::numeric_limits<int>::max();
|
||||
|
||||
while ((iEdge < endEdge) ) {
|
||||
if (iSplit < endSplit) {
|
||||
ii = splits[iSplit].i;
|
||||
} else {
|
||||
ii = imax;
|
||||
}
|
||||
if (ii == iEdge) {
|
||||
edgeSplits.push_back(splits[iSplit]);
|
||||
iSplit++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ii > iEdge) {
|
||||
if (!edgeSplits.empty()) { //save *iedge's splits
|
||||
newEdges = split1Edge(edges[iEdge],edgeSplits);
|
||||
result.insert(result.end(), newEdges.begin(), newEdges.end());
|
||||
edgeSplits.clear();
|
||||
} else {
|
||||
result.push_back(edges[iEdge]); //save *iedge
|
||||
}
|
||||
iEdge++; //next edge
|
||||
continue;
|
||||
}
|
||||
|
||||
if (iEdge > ii) {
|
||||
iSplit++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!edgeSplits.empty()) { //handle last batch
|
||||
newEdges = split1Edge(edges[iEdge],edgeSplits);
|
||||
result.insert(result.end(), newEdges.begin(), newEdges.end());
|
||||
edgeSplits.clear();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Edge> DrawViewPart::split1Edge(TopoDS_Edge e, std::vector<splitPoint> splits)
|
||||
{
|
||||
//Base::Console().Message("DVP::split1Edge - splits: %d\n",splits.size());
|
||||
std::vector<TopoDS_Edge> result;
|
||||
if (splits.empty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
Handle_Geom_Curve c = adapt.Curve().Curve();
|
||||
double first = BRepLProp_CurveTool::FirstParameter(adapt);
|
||||
double last = BRepLProp_CurveTool::LastParameter(adapt);
|
||||
if (first > last) {
|
||||
//TODO parms.reverse();
|
||||
Base::Console().Message("DVP::split1Edge - edge is backwards!\n");
|
||||
return result;
|
||||
}
|
||||
std::vector<double> parms;
|
||||
parms.push_back(first);
|
||||
for (auto& s:splits) {
|
||||
parms.push_back(s.param);
|
||||
}
|
||||
|
||||
parms.push_back(last);
|
||||
std::vector<double>::iterator pfirst = parms.begin();
|
||||
auto parms2 = parms.begin() + 1;
|
||||
std::vector<double>::iterator psecond = parms2;
|
||||
std::vector<double>::iterator pstop = parms.end();
|
||||
for (; psecond != pstop; pfirst++,psecond++) {
|
||||
try {
|
||||
BRepBuilderAPI_MakeEdge mkEdge(c, *pfirst, *psecond);
|
||||
if (mkEdge.IsDone()) {
|
||||
TopoDS_Edge e1 = mkEdge.Edge();
|
||||
result.push_back(e1);
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Base::Console().Message("LOG - DVP::split1Edge failed building edge segment\n");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Edge> DrawViewPart::splitEdge(std::vector<TopoDS_Vertex> splitPoints, TopoDS_Edge e)
|
||||
std::vector<splitPoint> DrawViewPart::sortSplits(std::vector<splitPoint>& s, bool ascend)
|
||||
{
|
||||
std::vector<TopoDS_Edge> result;
|
||||
if (splitPoints.empty()) {
|
||||
return result;
|
||||
std::vector<splitPoint> sorted = s;
|
||||
std::sort(sorted.begin(), sorted.end(), DrawViewPart::splitCompare);
|
||||
if (ascend) {
|
||||
std::reverse(sorted.begin(),sorted.end());
|
||||
}
|
||||
TopoDS_Vertex vStart = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex vEnd = TopExp::LastVertex(e);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
Handle_Geom_Curve c = adapt.Curve().Curve();
|
||||
//simple version for 1 splitPoint
|
||||
//TODO: handle case where e is split in multiple points (ie circular edge cuts line twice)
|
||||
// for some reason, BRepBuilderAPI_MakeEdge sometimes fails without reporting IsDone status or error, so we use try/catch
|
||||
try {
|
||||
BRepBuilderAPI_MakeEdge mkBuilder1(c, vStart ,splitPoints[0]);
|
||||
if (mkBuilder1.IsDone()) {
|
||||
TopoDS_Edge e1 = mkBuilder1.Edge();
|
||||
result.push_back(e1);
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Base::Console().Message("LOG - DVP::splitEdge failed building 1st edge\n");
|
||||
//return true if p1 "is greater than" p2
|
||||
/*static*/bool DrawViewPart::splitCompare(const splitPoint& p1, const splitPoint& p2)
|
||||
{
|
||||
bool result = false;
|
||||
if (p1.i > p2.i) {
|
||||
result = true;
|
||||
} else if (p1.i < p2.i) {
|
||||
result = false;
|
||||
} else if (p1.param > p2.param) {
|
||||
result = true;
|
||||
} else if (p1.param < p2.param) {
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
try{
|
||||
BRepBuilderAPI_MakeEdge mkBuilder2(c, splitPoints[0], vEnd);
|
||||
if (mkBuilder2.IsDone()) {
|
||||
TopoDS_Edge e2 = mkBuilder2.Edge();
|
||||
result.push_back(e2);
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Base::Console().Message("LOG - DVP::splitEdge failed building 2nd edge\n");
|
||||
//return true if p1 "is equal to" p2
|
||||
/*static*/bool DrawViewPart::splitEqual(const splitPoint& p1, const splitPoint& p2)
|
||||
{
|
||||
bool result = false;
|
||||
if ((p1.i == p2.i) &&
|
||||
(fabs(p1.param - p2.param) < Precision::Confusion())) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -703,6 +812,35 @@ DrawViewSection* DrawViewPart::getSectionRef(void) const
|
|||
return result;
|
||||
}
|
||||
|
||||
void DrawViewPart::getRunControl()
|
||||
{
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/RunControl");
|
||||
m_interAlgo = hGrp->GetInt("InterAlgo", 2l);
|
||||
m_sectionEdges = hGrp->GetInt("ShowSectionEdges", 1l);
|
||||
m_handleFaces = hGrp->GetInt("HandleFaces", 1l);
|
||||
// Base::Console().Message("TRACE - DVP::getRunControl - interAlgo: %ld sectionFaces: %ld handleFaces: %ld\n",
|
||||
// m_interAlgo,m_sectionEdges,m_handleFaces);
|
||||
}
|
||||
|
||||
bool DrawViewPart::handleFaces(void)
|
||||
{
|
||||
bool result = false;
|
||||
if (m_handleFaces == 1l) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DrawViewPart::showSectionEdges(void)
|
||||
{
|
||||
bool result = false;
|
||||
if (m_sectionEdges == 1l) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject *DrawViewPart::getPyObject(void)
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
|
|
|
@ -52,6 +52,11 @@ class DrawHatch;
|
|||
|
||||
namespace TechDraw
|
||||
{
|
||||
struct splitPoint {
|
||||
int i;
|
||||
Base::Vector3d v;
|
||||
double param;
|
||||
};
|
||||
class DrawViewSection;
|
||||
|
||||
class TechDrawExport DrawViewPart : public DrawView
|
||||
|
@ -109,6 +114,9 @@ public:
|
|||
|
||||
virtual short mustExecute() const;
|
||||
|
||||
bool handleFaces(void);
|
||||
bool showSectionEdges(void);
|
||||
|
||||
/** @name methods overide Feature */
|
||||
//@{
|
||||
/// recalculate the Feature
|
||||
|
@ -130,9 +138,10 @@ protected:
|
|||
void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center);
|
||||
void extractFaces();
|
||||
|
||||
bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, bool allowEnds = false);
|
||||
std::vector<TopoDS_Edge> splitEdge(std::vector<TopoDS_Vertex> splitPoints, TopoDS_Edge e);
|
||||
double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2) const; //probably sb static or DrawUtil
|
||||
bool isOnEdge(TopoDS_Edge e, TopoDS_Vertex v, double& param, bool allowEnds = false);
|
||||
std::vector<TopoDS_Edge> splitEdges(std::vector<TopoDS_Edge> orig, std::vector<splitPoint> splits);
|
||||
std::vector<TopoDS_Edge> split1Edge(TopoDS_Edge e, std::vector<splitPoint> splitPoints);
|
||||
double simpleMinDist(TopoDS_Shape s1, TopoDS_Shape s2); //const; //probably sb static or DrawUtil
|
||||
|
||||
//Projection parameter space
|
||||
void saveParamSpace(const Base::Vector3d& direction,
|
||||
|
@ -141,7 +150,14 @@ protected:
|
|||
Base::Vector3d vDir; //paperspace Y
|
||||
Base::Vector3d wDir; //paperspace Z
|
||||
Base::Vector3d shapeCentroid;
|
||||
int m_interAlgo;
|
||||
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);
|
||||
void getRunControl(void);
|
||||
|
||||
long int m_interAlgo;
|
||||
long int m_sectionEdges;
|
||||
long int m_handleFaces;
|
||||
|
||||
private:
|
||||
static App::PropertyFloatConstraint::Constraints floatRange;
|
||||
|
|
|
@ -95,8 +95,6 @@ DrawViewSection::DrawViewSection()
|
|||
|
||||
ADD_PROPERTY_TYPE(ShowCutSurface ,(true),fgroup,App::Prop_None,"Show the cut surface");
|
||||
ADD_PROPERTY_TYPE(CutSurfaceColor,(fcColor),fgroup,App::Prop_None,"The color to shade the cut surface");
|
||||
|
||||
geometryObject = new TechDrawGeometry::GeometryObject();
|
||||
}
|
||||
|
||||
DrawViewSection::~DrawViewSection()
|
||||
|
@ -120,6 +118,10 @@ short DrawViewSection::mustExecute() const
|
|||
return TechDraw::DrawView::mustExecute();
|
||||
}
|
||||
|
||||
void DrawViewSection::onChanged(const App::Property* prop)
|
||||
{
|
||||
DrawView::onChanged(prop);
|
||||
}
|
||||
App::DocumentObjectExecReturn *DrawViewSection::execute(void)
|
||||
{
|
||||
App::DocumentObject* link = Source.getValue();
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
//@{
|
||||
/// recalculate the Feature
|
||||
virtual App::DocumentObjectExecReturn *execute(void);
|
||||
// virtual void onChanged(const App::Property* prop);
|
||||
virtual void onChanged(const App::Property* prop);
|
||||
//@}
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
|
|
|
@ -65,11 +65,13 @@
|
|||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "DrawUtil.h"
|
||||
#include "GeometryObject.h"
|
||||
|
||||
//#include <QDebug>
|
||||
|
||||
using namespace TechDrawGeometry;
|
||||
using namespace TechDraw;
|
||||
using namespace std;
|
||||
|
||||
struct EdgePoints {
|
||||
|
@ -79,10 +81,11 @@ struct EdgePoints {
|
|||
|
||||
//debugging routine signatures
|
||||
const char* _printBool(bool b);
|
||||
void _dumpEdge(char* label, int i, TopoDS_Edge e);
|
||||
|
||||
|
||||
GeometryObject::GeometryObject() : Tolerance(0.05f), Scale(1.f)
|
||||
GeometryObject::GeometryObject(DrawView* parent) :
|
||||
Tolerance(0.05f),
|
||||
Scale(1.f),
|
||||
m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -157,7 +160,8 @@ void GeometryObject::projectShape(const TopoDS_Shape& input,
|
|||
auto end = chrono::high_resolution_clock::now();
|
||||
auto diff = end - start;
|
||||
double diffOut = chrono::duration <double, milli> (diff).count();
|
||||
Base::Console().Log("TIMING - GO spent: %.3f millisecs in HLRBRep_Algo & co\n",diffOut);
|
||||
Base::Console().Log("TIMING - %s GO spent: %.3f millisecs in HLRBRep_Algo & co\n",m_parent->getNameInDocument(),diffOut);
|
||||
|
||||
try {
|
||||
HLRBRep_HLRToShape hlrToShape(brep_hlr);
|
||||
|
||||
|
@ -244,7 +248,11 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca
|
|||
for (int i = 1 ; edges.More(); edges.Next(),i++) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
|
||||
if (edge.IsNull()) {
|
||||
Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i);
|
||||
//Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i);
|
||||
continue;
|
||||
}
|
||||
if (DrawUtil::isZeroEdge(edge)) {
|
||||
Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is zeroEdge\n",i);
|
||||
continue;
|
||||
}
|
||||
base = BaseGeom::baseFactory(edge);
|
||||
|
@ -702,18 +710,6 @@ void debugEdge(const TopoDS_Edge &e)
|
|||
}*/
|
||||
|
||||
|
||||
void _dumpEdge(char* label, int i, TopoDS_Edge e)
|
||||
{
|
||||
BRepAdaptor_Curve adapt(e);
|
||||
double start = BRepLProp_CurveTool::FirstParameter(adapt);
|
||||
double end = BRepLProp_CurveTool::LastParameter(adapt);
|
||||
BRepLProp_CLProps propStart(adapt,start,0,Precision::Confusion());
|
||||
const gp_Pnt& vStart = propStart.Value();
|
||||
BRepLProp_CLProps propEnd(adapt,end,0,Precision::Confusion());
|
||||
const gp_Pnt& vEnd = propEnd.Value();
|
||||
Base::Console().Message("%s edge:%d start:(%.3f,%.3f,%.3f)/%0.3f end:(%.2f,%.3f,%.3f)/%.3f\n",label,i,
|
||||
vStart.X(),vStart.Y(),vStart.Z(),start,vEnd.X(),vEnd.Y(),vEnd.Z(),end);
|
||||
}
|
||||
|
||||
const char* _printBool(bool b)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "DrawView.h"
|
||||
#include "Geometry.h"
|
||||
|
||||
namespace TechDrawGeometry
|
||||
|
@ -51,7 +52,7 @@ class TechDrawExport GeometryObject
|
|||
{
|
||||
public:
|
||||
/// Constructor
|
||||
GeometryObject();
|
||||
GeometryObject(TechDraw::DrawView* parent);
|
||||
virtual ~GeometryObject();
|
||||
|
||||
void clear();
|
||||
|
@ -119,6 +120,8 @@ protected:
|
|||
|
||||
double Tolerance;
|
||||
double Scale;
|
||||
|
||||
TechDraw::DrawView* m_parent;
|
||||
};
|
||||
|
||||
} //namespace TechDrawGeometry
|
||||
|
|
Loading…
Reference in New Issue
Block a user