Section face positioning/display

This commit is contained in:
WandererFan
2016-03-12 20:35:32 -05:00
committed by wmayer
parent af7d7f3118
commit 8cbd6d0b23
19 changed files with 553 additions and 345 deletions

View File

@@ -76,8 +76,6 @@ using namespace std;
// DrawViewPart
//===========================================================================
Base::Vector3d _getValidXDir(const DrawViewPart *me);
App::PropertyFloatConstraint::Constraints DrawViewPart::floatRange = {0.01f,5.0f,0.05f};
PROPERTY_SOURCE(TechDraw::DrawViewPart, TechDraw::DrawView)
@@ -124,8 +122,18 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
return new App::DocumentObjectExecReturn("FVP - Linked shape object is empty");
}
geometryObject->setTolerance(Tolerance.getValue());
geometryObject->setScale(Scale.getValue());
try {
buildGeometryObject(shape);
gp_Pnt inputCenter = TechDrawGeometry::findCentroid(shape,
Direction.getValue(),
getValidXDir());
TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(shape,
inputCenter,
//Direction.getValue(),
//getValidXDir(),
Scale.getValue());
buildGeometryObject(mirroredShape,inputCenter);
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
@@ -184,13 +192,12 @@ void DrawViewPart::onChanged(const App::Property* prop)
//TODO: when scale changes, any Dimensions for this View sb recalculated. (might happen anyway if document is recomputed?)
}
void DrawViewPart::buildGeometryObject(TopoDS_Shape shape)
void DrawViewPart::buildGeometryObject(TopoDS_Shape shape, gp_Pnt& inputCenter)
{
geometryObject->setTolerance(Tolerance.getValue());
geometryObject->setScale(Scale.getValue());
geometryObject->initHLR(shape,
geometryObject->projectShape(shape,
inputCenter,
Direction.getValue(),
_getValidXDir(this));
getValidXDir());
geometryObject->extractGeometry(TechDrawGeometry::ecHARD,
true);
geometryObject->extractGeometry(TechDrawGeometry::ecOUTLINE,
@@ -281,7 +288,7 @@ TechDrawGeometry::BaseGeom *DrawViewPart::getCompleteEdge(int idx) const
TechDrawGeometry::BaseGeom* prjShape = 0;
try {
prjShape = geometryObject->projectEdge(shape, support, Direction.getValue(), _getValidXDir(this));
prjShape = geometryObject->projectEdge(shape, support, Direction.getValue(), getValidXDir());
}
catch(Standard_Failure) {
Base::Console().Error("getCompleteEdge - OCC Error - could not project Edge: %d\n",idx);
@@ -315,7 +322,7 @@ TechDrawGeometry::Vertex * DrawViewPart::getVertex(int idx) const
const TopoDS_Shape &support = static_cast<Part::Feature*>(link)->Shape.getValue();
//TODO: Make sure prjShape gets deleted
TechDrawGeometry::Vertex *prjShape = geometryObject->projectVertex(shape, support, Direction.getValue(), _getValidXDir(this));
TechDrawGeometry::Vertex *prjShape = geometryObject->projectVertex(shape, support, Direction.getValue(), getValidXDir());
//Base::Console().Log("vert %f, %f \n", prjShape->pnt.fX, prjShape->pnt.fY);
return prjShape;
}
@@ -432,9 +439,9 @@ bool DrawViewPart::hasGeometry(void) const
return result;
}
Base::Vector3d _getValidXDir(const DrawViewPart *me)
Base::Vector3d DrawViewPart::getValidXDir() const
{
Base::Vector3d xDir = me->XAxisDirection.getValue();
Base::Vector3d xDir = XAxisDirection.getValue();
if (xDir.Length() == 0) {
Base::Console().Warning("XAxisDirection has zero length - using (1,0,0)\n");
xDir = Base::Vector3d(1.0,0.0,0.0);
@@ -453,6 +460,18 @@ void DrawViewPart::dumpVertexRefs(char* text) const
}
}
void DrawViewPart::dumpVertexes(const char* text, const TopoDS_Shape& s)
{
Base::Console().Message("DUMP - %s\n",text);
TopExp_Explorer expl(s, TopAbs_VERTEX);
int i;
for (i = 1 ; expl.More(); expl.Next(),i++) {
const TopoDS_Vertex& v = TopoDS::Vertex(expl.Current());
gp_Pnt pnt = BRep_Tool::Pnt(v);
Base::Console().Message("v%d: (%.3f,%.3f,%.3f)\n",i,pnt.X(),pnt.Y(),pnt.Z());
}
}
PyObject *DrawViewPart::getPyObject(void)
{
if (PythonObject.is(Py::_None())) {

View File

@@ -106,10 +106,12 @@ public:
virtual PyObject *getPyObject(void);
void dumpVertexRefs(char* text) const;
void dumpVertexes(const char* text, const TopoDS_Shape& s);
protected:
void onChanged(const App::Property* prop);
void buildGeometryObject(TopoDS_Shape shape);
Base::Vector3d getValidXDir() const;
void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center);
TechDrawGeometry::GeometryObject *geometryObject;
Base::BoundBox3d bbox;

View File

@@ -31,6 +31,14 @@
#include <HLRBRep_Algo.hxx>
#include <TopoDS_Shape.hxx>
#include <HLRTopoBRep_OutLiner.hxx>
#include <BRepBndLib.hxx>
#include <Bnd_Box.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
//#include <BRepAPI_MakeOutLine.hxx>
#include <HLRAlgo_Projector.hxx>
#include <HLRBRep_ShapeBounds.hxx>
@@ -145,7 +153,7 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void)
return new App::DocumentObjectExecReturn("Section Plane doesn't intersect part");
}
bb.Enlarge(1.0); // Enlarge the bounding box to prevent any clipping
//bb.Enlarge(1.0); // Enlarge the bounding box to prevent any clipping
// Gather the points
std::vector<Base::Vector3d> pnts;
@@ -200,41 +208,48 @@ App::DocumentObjectExecReturn *DrawViewSection::execute(void)
TopoDS_Shape myShape = BuilderCopy.Shape();
BRepAlgoAPI_Cut mkCut(myShape, prism);
// Let's check if the fusion has been successful
if (!mkCut.IsDone())
return new App::DocumentObjectExecReturn("Section cut has failed");
// Cache the sectionShape
sectionShape = mkCut.Shape();
TopoDS_Shape rawShape = mkCut.Shape();
geometryObject->setTolerance(Tolerance.getValue());
geometryObject->setScale(Scale.getValue());
try {
buildGeometryObject(sectionShape);
gp_Pnt inputCenter = TechDrawGeometry::findCentroid(rawShape,
Direction.getValue(),
getValidXDir());
TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape,
inputCenter,
Scale.getValue());
buildGeometryObject(mirroredShape,inputCenter);
TopoDS_Compound sectionCompound = findSectionPlaneIntersections(rawShape);
TopoDS_Shape mirroredSection = TechDrawGeometry::mirrorShape(sectionCompound,
inputCenter,
Scale.getValue());
TopoDS_Compound newFaces;
BRep_Builder builder;
builder.MakeCompound(newFaces);
TopExp_Explorer expl(mirroredSection, TopAbs_FACE);
for (int i = 1 ; expl.More(); expl.Next(),i++) {
const TopoDS_Face& face = TopoDS::Face(expl.Current());
TopoDS_Face pFace = projectFace(face,
inputCenter,
Direction.getValue(),
getValidXDir());
builder.Add(newFaces,pFace);
}
sectionFaces = newFaces;
}
catch (Standard_Failure) {
Handle_Standard_Failure e1 = Standard_Failure::Caught();
Base::Console().Log("DrawViewSection::execute - extractGeometry failed: %s\n",e1->GetMessageString());
Base::Console().Log("DrawViewSection::execute - building Section shape failed: %s\n",e1->GetMessageString());
return new App::DocumentObjectExecReturn(e1->GetMessageString());
}
TopoDS_Compound sectionFaces;
try {
sectionFaces = getSectionFaces();
}
catch (Standard_Failure) {
Handle_Standard_Failure e2 = Standard_Failure::Caught();
Base::Console().Log("DrawViewSection::execute - getSectionFaces failed: %s\n",e2->GetMessageString());
return new App::DocumentObjectExecReturn(e2->GetMessageString());
}
if (!sectionFaces.IsNull()) {
//TODO: do something with sectionFaces
//?add to GeometryObject faceGeom? but need to tag these faces as "special"
//how does QGIVSection know to shade these faces??
}
// TODO: touch references? see DrawViewPart.execute()
touch();
return DrawView::execute(); //note: not DrawViewPart
return DrawView::execute();
}
gp_Pln DrawViewSection::getSectionPlane() const
@@ -245,29 +260,29 @@ gp_Pln DrawViewSection::getSectionPlane() const
return gp_Pln(gp_Pnt(plnPnt.x, plnPnt.y, plnPnt.z), gp_Dir(plnNorm.x, plnNorm.y, plnNorm.z));
}
//! tries to find the intersection of the section plane with the sectionShape (a collection of planar faces)
TopoDS_Compound DrawViewSection::getSectionFaces(void)
//! tries to find the intersection of the section plane with the shape giving a collection of planar faces
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
{
TopoDS_Compound result;
if(sectionShape.IsNull()){
//throw Base::Exception("Sectional View sectionShape is Empty");
Base::Console().Log("DrawViewSection::getSectionSurface - Sectional View sectionShape is Empty\n");
if(shape.IsNull()){
Base::Console().Log("DrawViewSection::getSectionSurface - Sectional View shape is Empty\n");
return result;
}
gp_Pln pln = getSectionPlane();
gp_Pln plnSection = getSectionPlane();
BRep_Builder builder;
builder.MakeCompound(result);
// Iterate through all faces
TopExp_Explorer expFaces(sectionShape, TopAbs_FACE);
for ( ; expFaces.More(); expFaces.Next()) {
TopExp_Explorer expFaces(shape, TopAbs_FACE);
int i;
for (i = 1 ; expFaces.More(); expFaces.Next(), i++) {
const TopoDS_Face& face = TopoDS::Face(expFaces.Current());
BRepAdaptor_Surface adapt(face);
if (adapt.GetType() == GeomAbs_Plane){
gp_Pln plane = adapt.Plane();
if(plane.Contains(pln.Location(), Precision::Confusion()) && plane.Axis().IsParallel(pln.Axis(), Precision::Angular())) {
gp_Pln plnFace = adapt.Plane();
if(plnSection.Contains(plnFace.Location(), Precision::Confusion()) &&
plnFace.Axis().IsParallel(plnSection.Axis(), Precision::Angular())) {
builder.Add(result, face);
}
}
@@ -275,6 +290,152 @@ TopoDS_Compound DrawViewSection::getSectionFaces(void)
return result;
}
//! get display geometry for Section faces
std::vector<TechDrawGeometry::Face*> DrawViewSection::getFaceGeometry()
{
std::vector<TechDrawGeometry::Face*> result;
//TopoDS_Compound c = getSectionFaces(); //get projected section faces?
TopoDS_Compound c = sectionFaces;
//for face in c
TopExp_Explorer faces(c, TopAbs_FACE);
for (; faces.More(); faces.Next()) {
TechDrawGeometry::Face* f = new TechDrawGeometry::Face();
const TopoDS_Face& face = TopoDS::Face(faces.Current());
TopExp_Explorer wires(face, TopAbs_WIRE);
for (; wires.More(); wires.Next()) {
TechDrawGeometry::Wire* w = new TechDrawGeometry::Wire();
const TopoDS_Wire& wire = TopoDS::Wire(wires.Current());
TopExp_Explorer edges(wire, TopAbs_EDGE);
for (; edges.More(); edges.Next()) {
const TopoDS_Edge& edge = TopoDS::Edge(edges.Current());
TechDrawGeometry::BaseGeom* base = TechDrawGeometry::BaseGeom::baseFactory(edge);
w->geoms.push_back(base);
}
f->wires.push_back(w);
}
result.push_back(f);
}
return result;
}
//! project a single face using HLR
TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
gp_Pnt faceCenter,
const Base::Vector3d &direction,
const Base::Vector3d &xaxis)
{
if(face.IsNull()) {
throw Base::Exception("DrawViewSection::projectFace - input Face is NULL");
return TopoDS_Face();
}
gp_Ax2 transform;
transform = gp_Ax2(faceCenter,
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(face);
HLRAlgo_Projector projector( transform );
brep_hlr->Projector(projector);
brep_hlr->Update();
brep_hlr->Hide();
HLRBRep_HLRToShape hlrToShape(brep_hlr);
TopoDS_Shape hardEdges = hlrToShape.VCompound();
TopoDS_Shape outEdges = hlrToShape.OutLineVCompound();
std::vector<TopoDS_Edge> faceEdges;
TopExp_Explorer expl(hardEdges, TopAbs_EDGE);
int i;
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);
continue;
}
faceEdges.push_back(edge);
}
expl.Init(outEdges, TopAbs_EDGE);
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);
continue;
}
faceEdges.push_back(edge);
}
//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);
if (!faceWires.empty()) {
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(faceWires);
if (sortedWires.empty()) {
return projectedFace;
}
BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes?
std::vector<TopoDS_Wire>::iterator itWire = (sortedWires.begin()) + 1; //starting with second face
for (; itWire != sortedWires.end(); itWire++) {
mkFace.Add(*itWire);
}
projectedFace = mkFace.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

@@ -27,10 +27,14 @@
#include <App/PropertyLinks.h>
#include <App/FeaturePython.h>
#include <TopoDS_Compound.hxx>
#include "DrawViewPart.h"
#include "Geometry.h"
class gp_Pln;
class TopoDS_Compound;
class TopoDS_Face;
namespace TechDraw
{
@@ -66,11 +70,20 @@ public:
}
public:
TopoDS_Compound getSectionFaces(void);
std::vector<TechDrawGeometry::Face*> getFaceGeometry();
protected:
TopoDS_Shape sectionShape;
TopoDS_Shape sectionShape; //obs??
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

@@ -142,6 +142,76 @@ Base::Vector2D BaseGeom::getEndPoint()
return verts[1];
}
//!convert 1 OCC edge into 1 BaseGeom (static factory method)
BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
{
BaseGeom* result = NULL;
BRepAdaptor_Curve adapt(edge);
switch(adapt.GetType()) {
case GeomAbs_Circle: {
double f = adapt.FirstParameter();
double l = adapt.LastParameter();
gp_Pnt s = adapt.Value(f);
gp_Pnt e = adapt.Value(l);
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
Circle *circle = new Circle(edge);
//circle->extractType = extractionType;
result = circle;
} else {
AOC *aoc = new AOC(edge);
//aoc->extractType = extractionType;
result = aoc;
}
} break;
case GeomAbs_Ellipse: {
double f = adapt.FirstParameter();
double l = adapt.LastParameter();
gp_Pnt s = adapt.Value(f);
gp_Pnt e = adapt.Value(l);
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
Ellipse *ellipse = new Ellipse(edge);
//ellipse->extractType = extractionType;
result = ellipse;
} else {
AOE *aoe = new AOE(edge);
//aoe->extractType = extractionType;
result = aoe;
}
} break;
case GeomAbs_BSplineCurve: {
BSpline *bspline = 0;
Generic* gen = NULL;
try {
bspline = new BSpline(edge);
//bspline->extractType = extractionType;
if (bspline->isLine()) {
gen = new Generic(edge);
//gen->extractType = extractionType;
result = gen;
delete bspline;
} else {
result = bspline;
}
break;
}
catch (Standard_Failure) {
delete bspline;
delete gen;
bspline = 0;
// Move onto generating a primitive
}
}
default: {
Generic *primitive = new Generic(edge);
//primitive->extractType = extractionType;
result = primitive;
} break;
}
return result;
}
Ellipse::Ellipse(const TopoDS_Edge &e)
{
geomType = ELLIPSE;
@@ -309,27 +379,6 @@ bool BSpline::isLine()
result = true;
}
return result;
#if 0
bool result = true;
std::vector<BezierSegment>::iterator iSeg = segments.begin();
double slope;
if ((*iSeg).poles == 2) {
slope = ((*iSeg).pnts[1].fY - (*iSeg).pnts[0].fY) /
((*iSeg).pnts[1].fX - (*iSeg).pnts[0].fX); //always at least 2 points?
}
for (; iSeg != segments.end(); iSeg++) {
if ((*iSeg).poles != 2) {
result = false;
break;
}
double newSlope = ((*iSeg).pnts[1].fY - (*iSeg).pnts[0].fY) / ((*iSeg).pnts[1].fX - (*iSeg).pnts[0].fX);
if (fabs(newSlope - slope) > Precision::Confusion()) {
result = false;
break;
}
}
return result;
#endif
}
//**** Vertex

View File

@@ -73,6 +73,8 @@ public:
std::vector<Base::Vector2D> findEndPoints();
Base::Vector2D getStartPoint();
Base::Vector2D getEndPoint();
public: //class wide methods
static BaseGeom* baseFactory(TopoDS_Edge edge);
};
class TechDrawExport Circle: public BaseGeom
@@ -171,17 +173,21 @@ public:
std::vector<Base::Vector2D> points;
};
/// Simple Collection of geometric features based on BaseGeom inherited classes in order
struct TechDrawExport Wire
class TechDrawExport Wire
{
public:
Wire();
~Wire();
std::vector<BaseGeom *> geoms;
};
/// Simple Collection of geometric features based on BaseGeom inherited classes in order
struct TechDrawExport Face
class TechDrawExport Face
{
public:
Face();
~Face();
std::vector<Wire *> wires;

View File

@@ -73,6 +73,7 @@
# include <BRepTools_WireExplorer.hxx>
# include <ShapeFix_Wire.hxx>
# include <BRepProj_Projection.hxx>
#include <BRepLib.hxx>
# include <BRepAdaptor_HCurve.hxx>
# include <BRepAdaptor_CompCurve.hxx>
@@ -84,7 +85,8 @@
# include <Approx_Curve3d.hxx>
# include <BRepAdaptor_HCurve.hxx>
# include <Handle_HLRBRep_Data.hxx>
#include <Handle_HLRBRep_Algo.hxx>
#include <Handle_HLRBRep_Data.hxx>
# include <Geom_BSplineCurve.hxx>
# include <Geom_BezierCurve.hxx>
# include <GeomConvert_BSplineCurveToBezierCurve.hxx>
@@ -103,7 +105,7 @@
# include <Mod/Part/App/PartFeature.h>
# include "GeometryObject.h"
#include "GeometryObject.h"
//#include <QDebug>
@@ -120,7 +122,7 @@ const char* _printBool(bool b);
void _dumpEdge(char* label, int i, TopoDS_Edge e);
GeometryObject::GeometryObject() : brep_hlr(NULL), Tolerance(0.05f), Scale(1.f)
GeometryObject::GeometryObject() : Tolerance(0.05f), Scale(1.f)
{
}
@@ -167,50 +169,25 @@ void GeometryObject::clear()
edgeReferences.clear();
}
//!set up a hidden line remover and load a shape into it
void GeometryObject::initHLR(const TopoDS_Shape &input,
const Base::Vector3d &direction,
const Base::Vector3d &xAxis)
//!set up a hidden line remover and project a shape with it
void GeometryObject::projectShape(const TopoDS_Shape& input,
const gp_Pnt& inputCenter,
const Base::Vector3d& direction,
const Base::Vector3d& xAxis)
{
// Clear previous Geometry and References that may have been stored
//TODO: hate losing references on recompute! if Shape has changed, aren't reference potentially invalid anyway?
clear();
if (brep_hlr) {
if (brep_hlr->NbShapes()) { //TODO: hack. in ProjGroupItems sometimes brep_hlr has no shapes when we get here. why??
brep_hlr->Remove(1); //remove the old shape from brep (would we ever have > 1 shape?)
}
}
///TODO: Consider whether it would be possible/beneficial to cache some of this effort (eg don't do scale in OpenCASCADE land) IR
TopoDS_Shape transShape;
gp_Pnt inputCentre;
Handle_HLRBRep_Algo brep_hlr = NULL;
try {
inputCentre = findCentroid(input, direction, xAxis);
}
catch (...) {
Base::Console().Log("GeometryObject::initHLR - findCentroid failed.\n");
return;
}
try {
// Make tempTransform scale the object around it's centre point and
// mirror about the Y axis
gp_Trsf tempTransform;
tempTransform.SetScale(inputCentre, Scale);
gp_Trsf mirrorTransform;
mirrorTransform.SetMirror( gp_Ax2(inputCentre, gp_Dir(0, 1, 0)) );
tempTransform.Multiply(mirrorTransform);
// Apply that transform to the shape. This should preserve the centre.
BRepBuilderAPI_Transform mkTrf(input, tempTransform);
transShape = mkTrf.Shape();
brep_hlr = new HLRBRep_Algo(); //leak? when does this get freed? handle/smart pointer
brep_hlr->Add(transShape);
brep_hlr = new HLRBRep_Algo(); //leak? when does this get freed? handle/smart pointer?
brep_hlr->Add(input);
// Project the shape into view space with the object's centroid
// at the origin.
gp_Ax2 viewAxis;
viewAxis = gp_Ax2(inputCentre,
viewAxis = gp_Ax2(inputCenter,
gp_Dir(direction.x, direction.y, direction.z),
gp_Dir(xAxis.x, xAxis.y, xAxis.z));
HLRAlgo_Projector projector( viewAxis );
@@ -219,28 +196,56 @@ void GeometryObject::initHLR(const TopoDS_Shape &input,
brep_hlr->Hide();
}
catch (...) {
Standard_Failure::Raise("GeometryObject::initHLR - error occurred while projecting shape");
Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape");
}
try {
HLRBRep_HLRToShape hlrToShape(brep_hlr);
visHard = hlrToShape.VCompound();
visSmooth = hlrToShape.Rg1LineVCompound();
visSeam = hlrToShape.RgNLineVCompound();
visOutline = hlrToShape.OutLineVCompound();
visIso = hlrToShape.IsoLineVCompound();
hidHard = hlrToShape.HCompound();
hidSmooth = hlrToShape.Rg1LineHCompound();
hidSeam = hlrToShape.RgNLineHCompound();
hidOutline = hlrToShape.OutLineHCompound();
hidIso = hlrToShape.IsoLineHCompound();
BRepLib::BuildCurves3d(visHard);
BRepLib::BuildCurves3d(visSmooth);
BRepLib::BuildCurves3d(visSeam);
BRepLib::BuildCurves3d(visOutline);
BRepLib::BuildCurves3d(visIso);
BRepLib::BuildCurves3d(hidHard);
BRepLib::BuildCurves3d(hidSmooth);
BRepLib::BuildCurves3d(hidSeam);
BRepLib::BuildCurves3d(hidOutline);
BRepLib::BuildCurves3d(hidIso);
}
catch (...) {
Standard_Failure::Raise("GeometryObject::projectShape - error occurred while extracting edges");
}
}
//!add edges meeting filter criteria for category, visibility
void GeometryObject::extractGeometry(edgeClass category, bool visible)
{
HLRBRep_HLRToShape hlrToShape(brep_hlr);
TopoDS_Shape filtEdges;
if (visible) {
switch (category) {
case ecHARD:
filtEdges = hlrToShape.VCompound();
filtEdges = visHard;
break;
case ecOUTLINE:
filtEdges = hlrToShape.OutLineVCompound();
filtEdges = visOutline;
break;
case ecSMOOTH:
filtEdges = hlrToShape.Rg1LineVCompound();
filtEdges = visSmooth;
break;
case ecSEAM:
filtEdges = hlrToShape.RgNLineHCompound();
filtEdges = visSeam;
break;
default:
Base::Console().Warning("GeometryObject::ExtractGeometry - unsupported visible edgeClass: %d\n",category);
@@ -249,7 +254,7 @@ void GeometryObject::extractGeometry(edgeClass category, bool visible)
} else {
switch (category) {
case ecHARD:
filtEdges = hlrToShape.HCompound();
filtEdges = hidHard;
break;
//more cases here?
default:
@@ -281,7 +286,7 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca
Base::Console().Log("INFO - GO::addGeomFromCompound - edge: %d is NULL\n",i);
continue;
}
base = edgeToBase(edge);
base = BaseGeom::baseFactory(edge);
base->classOfEdge = category;
base->visible = visible;
edgeGeom.push_back(base);
@@ -290,7 +295,7 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca
//add vertices of new edge if not already in list
if (visible) {
BaseGeom* lastAdded = edgeGeom.back();
//if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? edgeToBase always returns a Base?)
//if (edgeGeom.empty()) {horrible_death();} //back() undefined behavior (can't happen? baseFactory always returns a Base?)
bool v1Add = true, v2Add = true;
TechDrawGeometry::Vertex* v1 = new TechDrawGeometry::Vertex(lastAdded->getStartPoint());
TechDrawGeometry::Vertex* v2 = new TechDrawGeometry::Vertex(lastAdded->getEndPoint());
@@ -322,110 +327,11 @@ void GeometryObject::addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass ca
}
}
//!convert 1 OCC edge into 1 BaseGeom
BaseGeom* GeometryObject::edgeToBase(TopoDS_Edge edge)
{
BaseGeom* result = NULL;
BRepAdaptor_Curve adapt(edge);
switch(adapt.GetType()) {
case GeomAbs_Circle: {
double f = adapt.FirstParameter();
double l = adapt.LastParameter();
gp_Pnt s = adapt.Value(f);
gp_Pnt e = adapt.Value(l);
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
Circle *circle = new Circle(edge);
//circle->extractType = extractionType;
result = circle;
} else {
AOC *aoc = new AOC(edge);
//aoc->extractType = extractionType;
result = aoc;
}
} break;
case GeomAbs_Ellipse: {
double f = adapt.FirstParameter();
double l = adapt.LastParameter();
gp_Pnt s = adapt.Value(f);
gp_Pnt e = adapt.Value(l);
if (fabs(l-f) > 1.0 && s.SquareDistance(e) < 0.001) {
Ellipse *ellipse = new Ellipse(edge);
//ellipse->extractType = extractionType;
result = ellipse;
} else {
AOE *aoe = new AOE(edge);
//aoe->extractType = extractionType;
result = aoe;
}
} break;
case GeomAbs_BSplineCurve: {
BSpline *bspline = 0;
Generic* gen = NULL;
try {
bspline = new BSpline(edge);
//bspline->extractType = extractionType;
if (bspline->isLine()) {
gen = new Generic(edge);
//gen->extractType = extractionType;
result = gen;
delete bspline;
} else {
result = bspline;
}
break;
}
catch (Standard_Failure) {
delete bspline;
delete gen;
bspline = 0;
// Move onto generating a primitive
}
}
default: {
Generic *primitive = new Generic(edge);
//primitive->extractType = extractionType;
result = primitive;
} break;
}
return result;
}
//!find the 3D edges & vertices that correspond to 2D edges & vertices
void GeometryObject::update3DRefs()
{
}
gp_Pnt GeometryObject::findCentroid(const TopoDS_Shape &shape,
const Base::Vector3d &direction,
const Base::Vector3d &xAxis) const
{
gp_Ax2 viewAxis;
viewAxis = gp_Ax2(gp_Pnt(0, 0, 0),
gp_Dir(direction.x, -direction.y, direction.z),
gp_Dir(xAxis.x, -xAxis.y, xAxis.z)); // Y invert warning!
gp_Trsf tempTransform;
tempTransform.SetTransformation(viewAxis);
BRepBuilderAPI_Transform builder(shape, tempTransform);
Bnd_Box tBounds;
BRepBndLib::Add(builder.Shape(), tBounds);
tBounds.SetGap(0.0);
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
tBounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
Standard_Real x = (xMin + xMax) / 2.0,
y = (yMin + yMax) / 2.0,
z = (zMin + zMax) / 2.0;
// Get centroid back into object space
tempTransform.Inverted().Transforms(x, y, z);
return gp_Pnt(x, y, z);
}
/////////////// bbox routines
@@ -966,6 +872,66 @@ bool GeometryObject::findVertex(Base::Vector2D v)
return found;
}
/// utility non-class member functions
//! Returns the centroid of shape, as viewed according to direction and xAxis
gp_Pnt TechDrawGeometry::findCentroid(const TopoDS_Shape &shape,
const Base::Vector3d &direction,
const Base::Vector3d &xAxis)
{
gp_Ax2 viewAxis;
viewAxis = gp_Ax2(gp_Pnt(0, 0, 0),
gp_Dir(direction.x, -direction.y, direction.z),
gp_Dir(xAxis.x, -xAxis.y, xAxis.z)); // Y invert warning!
gp_Trsf tempTransform;
tempTransform.SetTransformation(viewAxis);
BRepBuilderAPI_Transform builder(shape, tempTransform);
Bnd_Box tBounds;
BRepBndLib::Add(builder.Shape(), tBounds);
tBounds.SetGap(0.0);
Standard_Real xMin, yMin, zMin, xMax, yMax, zMax;
tBounds.Get(xMin, yMin, zMin, xMax, yMax, zMax);
Standard_Real x = (xMin + xMax) / 2.0,
y = (yMin + yMax) / 2.0,
z = (zMin + zMax) / 2.0;
// Get centroid back into object space
tempTransform.Inverted().Transforms(x, y, z);
return gp_Pnt(x, y, z);
}
//!scales & mirrors a shape about a center
TopoDS_Shape TechDrawGeometry::mirrorShape(const TopoDS_Shape &input,
const gp_Pnt& inputCenter,
double scale)
{
TopoDS_Shape transShape;
try {
// Make tempTransform scale the object around it's centre point and
// mirror about the Y axis
// TODO: is this really always Y axis? sb whatever is vertical direction in projection?
gp_Trsf tempTransform;
tempTransform.SetScale(inputCenter, scale);
gp_Trsf mirrorTransform;
mirrorTransform.SetMirror( gp_Ax2(inputCenter, gp_Dir(0, 1, 0)) );
tempTransform.Multiply(mirrorTransform);
// Apply that transform to the shape. This should preserve the centre.
BRepBuilderAPI_Transform mkTrf(input, tempTransform);
transShape = mkTrf.Shape();
}
catch (...) {
Base::Console().Log("GeometryObject::mirrorShape - mirror/scale failed.\n");
return transShape;
}
return transShape;
}
/// debug functions
void _dumpEdgeData(char* label, int i, HLRBRep_EdgeData& ed)
{
Base::Console().Message("Dump of EdgeData for %s Edge: %d\n",label,i);

View File

@@ -23,8 +23,8 @@
#ifndef _TECHDRAW_GEOMETRYOBJECT_H
#define _TECHDRAW_GEOMETRYOBJECT_H
#include <Handle_HLRBRep_Algo.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>
#include <gp_Pnt.hxx>
#include <Base/Vector3D.h>
@@ -44,6 +44,16 @@ namespace TechDrawGeometry
class BaseGeom;
//! scales & mirrors a shape about a center
TopoDS_Shape TechDrawExport mirrorShape(const TopoDS_Shape &input,
const gp_Pnt& inputCenter,
double scale);
//! Returns the centroid of shape, as viewed according to direction and xAxis
gp_Pnt TechDrawExport findCentroid(const TopoDS_Shape &shape,
const Base::Vector3d &direction,
const Base::Vector3d &xAxis);
class TechDrawExport GeometryObject
{
public:
@@ -67,6 +77,7 @@ public:
const std::vector<int> & getEdgeRefs() const { return edgeReferences; };
const std::vector<int> & getFaceRefs() const { return faceReferences; };
//begin obs?
void projectSurfaces(const TopoDS_Shape &face,
const TopoDS_Shape &support,
const Base::Vector3d &direction,
@@ -80,15 +91,28 @@ public:
const TopoDS_Shape &support,
const Base::Vector3d &direction,
const Base::Vector3d &projXAxis) const;
//end obs?
void initHLR(const TopoDS_Shape &input,
void projectShape(const TopoDS_Shape &input,
const gp_Pnt& inputCenter,
const Base::Vector3d &direction,
const Base::Vector3d &xAxis);
void extractGeometry(edgeClass category, bool visible);
BaseGeom* edgeToBase(TopoDS_Edge edge);
void update3DRefs();
protected:
//HLR output
TopoDS_Shape visHard;
TopoDS_Shape visOutline;
TopoDS_Shape visSmooth;
TopoDS_Shape visSeam;
TopoDS_Shape visIso;
TopoDS_Shape hidHard;
TopoDS_Shape hidOutline;
TopoDS_Shape hidSmooth;
TopoDS_Shape hidSeam;
TopoDS_Shape hidIso;
void addGeomFromCompound(TopoDS_Shape edgeCompound, edgeClass category, bool visible);
/// Helper for calcBoundingBox()
@@ -124,14 +148,8 @@ protected:
std::vector<int> edgeReferences;
std::vector<int> faceReferences;
Handle_HLRBRep_Algo brep_hlr;
double Tolerance;
double Scale;
/// Returns the centroid of shape, as viewed according to direction and xAxis
gp_Pnt findCentroid(const TopoDS_Shape &shape,
const Base::Vector3d &direction,
const Base::Vector3d &xAxis) const;
};
} //namespace TechDrawGeometry