Fix Hatch path fp math

Fix section face painting
This commit is contained in:
WandererFan 2016-03-21 09:33:38 -04:00 committed by wmayer
parent a996c0a3af
commit 20de9af2c2
11 changed files with 154 additions and 137 deletions

View File

@ -28,6 +28,7 @@
# include <sstream>
#endif
#include <algorithm>
#include <HLRBRep_Algo.hxx>
#include <TopoDS_Shape.hxx>
@ -53,6 +54,12 @@
#include <TopTools_ListOfShape.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <BRep_Tool.hxx>
#include <BRepBndLib.hxx>
#include <Bnd_Box.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <Base/BoundBox.h>
#include <Base/Console.h>
@ -130,10 +137,12 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
getValidXDir());
TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(shape,
inputCenter,
//Direction.getValue(),
//getValidXDir(),
Scale.getValue());
buildGeometryObject(mirroredShape,inputCenter);
#if MOD_TECHDRAW_HANDLE_FACES
extractFaces();
#endif //#if MOD_TECHDRAW_HANDLE_FACES
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
@ -223,6 +232,32 @@ void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter)
bbox = geometryObject->calcBoundingBox();
}
//! make faces from the existing edge geometry
void DrawViewPart::extractFaces()
{
geometryObject->clearFaceGeom();
const std::vector<TechDrawGeometry::BaseGeom*>& goEdges = geometryObject->getEdgeGeometry();
std::vector<TechDrawGeometry::BaseGeom*>::const_iterator itEdge = goEdges.begin();
std::vector<TopoDS_Edge> occEdges;
for (;itEdge != goEdges.end(); itEdge++) {
occEdges.push_back((*itEdge)->occEdge);
}
//almost works. :(
std::vector<TopoDS_Wire> wires = connectEdges(occEdges);
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(wires,true); //smallest first
std::vector<TopoDS_Wire>::iterator itWire = sortedWires.begin();
for (; itWire != sortedWires.end(); itWire++) {
//version 1: 1 wire/face - no voids in face
TechDrawGeometry::Face* f = new TechDrawGeometry::Face();
const TopoDS_Wire& wire = (*itWire);
TechDrawGeometry::Wire* w = new TechDrawGeometry::Wire(wire);
f->wires.push_back(w);
geometryObject->addFaceGeom(f);
}
}
std::vector<TechDraw::DrawHatch*> DrawViewPart::getHatches() const
{
std::vector<TechDraw::DrawHatch*> result;
@ -425,6 +460,65 @@ Base::BoundBox3d DrawViewPart::getBoundingBox() const
return bbox;
}
//! build 1 or more wires from list of edges
//note disjoint edges won't be connected. have to be able to traverse all the edges
std::vector<TopoDS_Wire> DrawViewPart::connectEdges (std::vector<TopoDS_Edge>& edges)
{
std::vector<TopoDS_Wire> result;
Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
std::vector<TopoDS_Edge>::const_iterator itEdge = edges.begin();
for (; itEdge != edges.end(); itEdge++)
hEdges->Append(*itEdge);
//tolerance sb tolerance of DrawViewPart instead of Precision::Confusion()?
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_False, hWires);
int len = hWires->Length();
for(int i=1;i<=len;i++) {
TopoDS_Wire w = TopoDS::Wire(hWires->Value(i));
//if (BRep_Tool::IsClosed(w)) {
result.push_back(w);
//}
}
//delete hEdges; //does Handle<> take care of this?
//delete hWires;
return result;
}
//! return true if w1 bbox is bigger than w2 bbox
class DrawViewPart::wireCompare: public std::binary_function<const TopoDS_Wire&,
const TopoDS_Wire&, bool>
{
public:
bool operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2)
{
Bnd_Box box1, box2;
if (!w1.IsNull()) {
BRepBndLib::Add(w1, box1);
box1.SetGap(0.0);
}
if (!w2.IsNull()) {
BRepBndLib::Add(w2, box2);
box2.SetGap(0.0);
}
return box1.SquareExtent() > box2.SquareExtent();
}
};
//sort wires in descending order of bbox diagonal. if reversed, then ascending bbox diagonal
std::vector<TopoDS_Wire> DrawViewPart::sortWiresBySize(std::vector<TopoDS_Wire>& w, bool reverse)
{
std::vector<TopoDS_Wire> wires = w;
std::sort(wires.begin(), wires.end(), wireCompare());
if (reverse) {
std::reverse(wires.begin(),wires.end());
}
return wires;
}
bool DrawViewPart::hasGeometry(void) const
{
bool result = false;

View File

@ -109,11 +109,16 @@ public:
void dumpVertexes(const char* text, const TopoDS_Shape& s);
protected:
TechDrawGeometry::GeometryObject *geometryObject;
Base::BoundBox3d bbox;
void onChanged(const App::Property* prop);
Base::Vector3d getValidXDir() const;
void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center);
TechDrawGeometry::GeometryObject *geometryObject;
Base::BoundBox3d bbox;
void extractFaces();
std::vector<TopoDS_Wire> connectEdges (std::vector<TopoDS_Edge>& edges);
std::vector<TopoDS_Wire> sortWiresBySize(std::vector<TopoDS_Wire>& w, bool reverse = false);
class wireCompare;
private:
static App::PropertyFloatConstraint::Constraints floatRange;

View File

@ -351,7 +351,7 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
for (i = 1 ; expl.More(); expl.Next(),i++) {
const TopoDS_Edge& edge = TopoDS::Edge(expl.Current());
if (edge.IsNull()) {
Base::Console().Log("INFO - GO::addGeomFromCompound - hard edge: %d is NULL\n",i);
Base::Console().Log("INFO - GO::projectFace - hard edge: %d is NULL\n",i);
continue;
}
faceEdges.push_back(edge);
@ -360,7 +360,7 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
for (i = 1 ; expl.More(); expl.Next(),i++) {
const TopoDS_Edge& edge = TopoDS::Edge(expl.Current());
if (edge.IsNull()) {
Base::Console().Log("INFO - GO::addGeomFromCompound - outline edge: %d is NULL\n",i);
Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i);
continue;
}
faceEdges.push_back(edge);
@ -368,9 +368,9 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
//no guarantee HLR gives edges in any particular order, so have to build back into a face.
TopoDS_Face projectedFace;
std::vector<TopoDS_Wire> faceWires = DrawViewSection::connectEdges(faceEdges);
std::vector<TopoDS_Wire> faceWires = connectEdges(faceEdges); //from DrawViewPart
if (!faceWires.empty()) {
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(faceWires);
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(faceWires); //from DrawViewPart
if (sortedWires.empty()) {
return projectedFace;
}
@ -384,58 +384,6 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
return projectedFace;
}
//! connect edges into 1 or more wires
std::vector<TopoDS_Wire> DrawViewSection::connectEdges (std::vector<TopoDS_Edge>& edges)
{
std::vector<TopoDS_Wire> result;
Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
std::vector<TopoDS_Edge>::const_iterator itEdge = edges.begin();
for (; itEdge != edges.end(); itEdge++)
hEdges->Append(*itEdge);
//tolerance sb tolerance of DrawViewSection instead of Precision::Confusion()?
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, Precision::Confusion(), Standard_False, hWires);
int len = hWires->Length();
for(int i=1;i<=len;i++) {
result.push_back(TopoDS::Wire(hWires->Value(i)));
}
//delete hEdges; //does Handle<> take care of this?
//delete hWires;
return result;
}
//! return true if w1 bbox is bigger than w2 bbox
class DrawViewSection::wireCompare: public std::binary_function<const TopoDS_Wire&,
const TopoDS_Wire&, bool>
{
public:
bool operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2)
{
Bnd_Box box1, box2;
if (!w1.IsNull()) {
BRepBndLib::Add(w1, box1);
box1.SetGap(0.0);
}
if (!w2.IsNull()) {
BRepBndLib::Add(w2, box2);
box2.SetGap(0.0);
}
return box1.SquareExtent() > box2.SquareExtent();
}
};
//sort wires in descending order of size (bbox diagonal)
std::vector<TopoDS_Wire> DrawViewSection::sortWiresBySize(std::vector<TopoDS_Wire>& w)
{
std::vector<TopoDS_Wire> wires = w;
std::sort(wires.begin(), wires.end(), wireCompare());
return wires;
}
// Python Drawing feature ---------------------------------------------------------

View File

@ -73,17 +73,14 @@ public:
std::vector<TechDrawGeometry::Face*> getFaceGeometry();
protected:
TopoDS_Shape sectionShape; //obs??
TopoDS_Compound sectionFaces;
gp_Pln getSectionPlane() const;
TopoDS_Compound findSectionPlaneIntersections(const TopoDS_Shape& shape);
TopoDS_Face projectFace(const TopoDS_Shape &face,
gp_Pnt faceCenter,
const Base::Vector3d &direction,
const Base::Vector3d &xaxis);
std::vector<TopoDS_Wire> connectEdges (std::vector<TopoDS_Edge>& edges);
std::vector<TopoDS_Wire> sortWiresBySize(std::vector<TopoDS_Wire>& w);
TopoDS_Compound sectionFaces;
class wireCompare;
};
typedef App::FeaturePythonT<DrawViewSection> DrawViewSectionPython;

View File

@ -82,6 +82,16 @@ using namespace TechDrawGeometry;
// Collection of Geometric Features
Wire::Wire()
{
}
Wire::Wire(const TopoDS_Wire &w)
{
TopExp_Explorer edges(w, TopAbs_EDGE);
for (; edges.More(); edges.Next()) {
const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
TechDrawGeometry::BaseGeom* base = TechDrawGeometry::BaseGeom::baseFactory(edge);
geoms.push_back(base);
}
}
@ -396,11 +406,11 @@ bool Vertex::isEqual(Vertex* v, double tol)
extern "C" {
//! return a vector of BaseGeom*'s in tail to nose order
//could/should this be replaced by DVP::connectEdges?
std::vector<TechDrawGeometry::BaseGeom*> TechDrawExport chainGeoms(std::vector<TechDrawGeometry::BaseGeom*> geoms)
{
std::vector<TechDrawGeometry::BaseGeom*> result;
std::vector<bool> used(geoms.size(),false);
double tolerance = 0.0;
if (geoms.empty()) {
return result;
@ -413,7 +423,7 @@ std::vector<TechDrawGeometry::BaseGeom*> TechDrawExport chainGeoms(std::vector<T
Base::Vector2D atPoint = (geoms[0])->getEndPoint();
used[0] = true;
for (unsigned int i = 1; i < geoms.size(); i++) { //do size-1 more edges
getNextReturnVal next = nextGeom(atPoint,geoms,used,tolerance);
getNextReturnVal next = nextGeom(atPoint,geoms,used,Precision::Confusion());
if (next.index) { //found an unused edge with vertex == atPoint
TechDrawGeometry::BaseGeom* nextEdge = geoms.at(next.index);
used[next.index] = true;
@ -446,11 +456,11 @@ getNextReturnVal TechDrawExport nextGeom(Base::Vector2D atPoint,
if (used[index]) {
continue;
}
if (atPoint == (*itGeom)->getStartPoint()) {
if ((atPoint - (*itGeom)->getStartPoint()).Length() < tolerance) {
result.index = index;
result.reversed = false;
break;
} else if (atPoint == (*itGeom)->getEndPoint()) {
} else if ((atPoint - (*itGeom)->getEndPoint()).Length() < tolerance) {
result.index = index;
result.reversed = true;
break;

View File

@ -27,6 +27,7 @@
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
class BRepAdaptor_Curve;
@ -180,6 +181,7 @@ class TechDrawExport Wire
{
public:
Wire();
Wire(const TopoDS_Wire &w);
~Wire();
std::vector<BaseGeom *> geoms;
};

View File

@ -332,7 +332,17 @@ void GeometryObject::update3DRefs()
{
}
//! empty Face geometry
void GeometryObject::clearFaceGeom()
{
faceGeom.clear();
}
//! add a Face to Face Geometry
void GeometryObject::addFaceGeom(Face* f)
{
faceGeom.push_back(f);
}
/////////////// bbox routines
@ -667,54 +677,6 @@ TechDrawGeometry::Vertex * GeometryObject::projectVertex(const TopoDS_Shape &ver
#endif
}
//!only used by DrawViewSection, but code is #if 0, so obs?
//don't need anything projected. DVS already has Compound of section faces. just need to turn those into
// BaseGeom::Face with tag for shading? like addGeomFromCompound without verts
void GeometryObject::projectSurfaces(const TopoDS_Shape &face,
const TopoDS_Shape &support,
const Base::Vector3d &direction,
const Base::Vector3d &xaxis,
std::vector<TechDrawGeometry::Face *> &projFaces) const
{
if(face.IsNull()) {
throw Base::Exception("Projected shape is null");
return;
}
#if 0
gp_Pnt supportCentre = findCentroid(support, direction, xaxis);
// TODO: We used to invert Y twice here, make sure that wasn't intentional
gp_Trsf mat;
mat.SetMirror(gp_Ax2(supportCentre, gp_Dir(0, 1, 0)));
gp_Trsf matScale;
matScale.SetScale(supportCentre, Scale);
mat.Multiply(matScale);
BRepBuilderAPI_Transform mkTrfScale(face, mat);
gp_Ax2 transform;
transform = gp_Ax2(supportCentre,
gp_Dir(direction.x, direction.y, direction.z),
gp_Dir(xaxis.x, xaxis.y, xaxis.z));
HLRBRep_Algo *brep_hlr = new HLRBRep_Algo();
brep_hlr->Add(mkTrfScale.Shape());
HLRAlgo_Projector projector( transform );
brep_hlr->Projector(projector);
brep_hlr->Update();
brep_hlr->Hide();
Base::Console().Log("GeometryObject::projectSurfaces - projecting face\n");
// Extract Faces
std::vector<int> projFaceRefs;
extractFaces(brep_hlr, mkTrfScale.Shape(), true, WithSmooth, projFaces, projFaceRefs);
delete brep_hlr;
#endif
}
//! only ever called from fvp::getCompleteEdge which is only ever called from CmdCreateDim for true dims. so obs?
TechDrawGeometry::BaseGeom * GeometryObject::projectEdge(const TopoDS_Shape &edge,
const TopoDS_Shape &support,

View File

@ -78,11 +78,6 @@ public:
const std::vector<int> & getFaceRefs() const { return faceReferences; };
//begin obs?
void projectSurfaces(const TopoDS_Shape &face,
const TopoDS_Shape &support,
const Base::Vector3d &direction,
const Base::Vector3d &xaxis,
std::vector<TechDrawGeometry::Face *> &result) const;
BaseGeom* projectEdge(const TopoDS_Shape &edge,
const TopoDS_Shape &support,
const Base::Vector3d &direction,
@ -99,6 +94,8 @@ public:
const Base::Vector3d &xAxis);
void extractGeometry(edgeClass category, bool visible);
void update3DRefs();
void addFaceGeom(Face * f);
void clearFaceGeom();
protected:
//HLR output

View File

@ -45,9 +45,9 @@ using namespace TechDrawGui;
QGIFace::QGIFace(int ref) :
reference(ref),
//m_fill(Qt::NoBrush)
m_fill(Qt::NoBrush)
//m_fill(Qt::CrossPattern)
m_fill(Qt::Dense3Pattern)
//m_fill(Qt::Dense3Pattern)
//m_fill(Qt::Dense6Pattern)
{
setCacheMode(QGraphicsItem::NoCache);
@ -63,7 +63,7 @@ QGIFace::QGIFace(int ref) :
m_colPre = fcColor.asQColor();
//m_pen.setStyle(Qt::NoPen);
m_brush.setStyle(m_fill);
//m_brush.setStyle(m_fill);
setPrettyNormal();
}
@ -95,23 +95,23 @@ void QGIFace::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
void QGIFace::setPrettyNormal() {
m_pen.setColor(m_colNormal);
m_brush.setColor(m_colNormal);
//m_brush.setColor(m_colNormal);
setPen(m_pen);
setBrush(m_brush);
//setBrush(m_brush);
}
void QGIFace::setPrettyPre() {
m_pen.setColor(m_colPre);
m_brush.setColor(m_colPre);
//m_brush.setColor(m_colPre);
setPen(m_pen);
setBrush(m_brush);
//setBrush(m_brush);
}
void QGIFace::setPrettySel() {
m_pen.setColor(m_colSel);
m_brush.setColor(m_colSel);
//m_brush.setColor(m_colSel);
setPen(m_pen);
setBrush(m_brush);
//setBrush(m_brush);
}
void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
@ -119,8 +119,7 @@ void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * optio
//myOption.state &= ~QStyle::State_Selected; //temp for debugging
//m_pen.setColor(m_colCurrent);
setPen(m_pen);
setBrush(m_brush);
//setPen(m_pen);
//setBrush(m_brush);
QGraphicsPathItem::paint (painter, &myOption, widget);
}

View File

@ -287,12 +287,13 @@ void QGIViewPart::drawViewPart()
prepareGeometryChange();
#if MOD_TECHDRAW_HANDLE_FACES
// Draw Faces
const std::vector<TechDrawGeometry::Face *> &faceGeoms = viewPart->getFaceGeometry();
std::vector<TechDrawGeometry::Face *>::const_iterator fit = faceGeoms.begin();
QPen facePen;
facePen.setCosmetic(true);
QBrush faceBrush;
//QBrush faceBrush;
for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) {
QGIFace* newFace = drawFace(*fit);
newFace->setPen(facePen);
@ -303,6 +304,7 @@ void QGIViewPart::drawViewPart()
//std::stringstream faceId;
//faceId << "facePath" << i;
//_dumpPath(faceId.str().c_str(),facePath);
#endif //#if MOD_TECHDRAW_HANDLE_FACES
// Draw Hatches
std::vector<TechDraw::DrawHatch*> hatchObjs = viewPart->getHatches();
@ -433,7 +435,7 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f)
addToGroup(gFace);
gFace->setPos(0.0,0.0);
gFace->setPath(facePath);
_dumpPath("QGIVP.facePath",facePath);
//_dumpPath("QGIVP.facePath",facePath);
//gFace->setFlag(QGraphicsItem::ItemIsSelectable, true); ???
return gFace;

View File

@ -83,11 +83,12 @@ void QGIViewSection::drawSectionFace()
std::vector<TechDrawGeometry::Face *>::iterator fit = sectionFaces.begin();
QPen facePen;
facePen.setCosmetic(true);
//QBrush faceBrush;
QBrush faceBrush(QBrush(QColor(0,0,255,40))); //temp. sb preference or property.
for(; fit != sectionFaces.end(); fit++) {
QGIFace* newFace = drawFace(*fit);
newFace->setZValue(ZVALUE::SECTIONFACE);
newFace->setBrush(faceBrush);
newFace->setPen(facePen);
//newFace->setEyeCandy()
}
}