Py binding for EdgeWalker
refactor EdgeWalker code from DVP,DVS
This commit is contained in:
parent
27ff991d79
commit
9a93185f7e
|
@ -34,15 +34,12 @@
|
|||
#include "DrawViewDraft.h"
|
||||
#include "DrawViewSpreadsheet.h"
|
||||
|
||||
extern struct PyMethodDef TechDraw_methods[];
|
||||
|
||||
PyDoc_STRVAR(module_techdraw_doc,
|
||||
"This module is the TechDraw module.");
|
||||
|
||||
namespace TechDraw {
|
||||
extern PyObject* initModule();
|
||||
}
|
||||
|
||||
/* Python entry */
|
||||
extern "C" {
|
||||
void TechDrawExport initTechDraw()
|
||||
PyMODINIT_FUNC initTechDraw()
|
||||
{
|
||||
// load dependent module
|
||||
try {
|
||||
|
@ -53,7 +50,7 @@ void TechDrawExport initTechDraw()
|
|||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
return;
|
||||
}
|
||||
Py_InitModule3("TechDraw", TechDraw_methods, module_techdraw_doc); /* mod name, table ptr */
|
||||
(void)TechDraw::initModule();
|
||||
Base::Console().Log("Loading TechDraw module... done\n");
|
||||
|
||||
|
||||
|
@ -87,5 +84,3 @@ void TechDrawExport initTechDraw()
|
|||
TechDraw::DrawTemplatePython ::init();
|
||||
TechDraw::DrawViewSymbolPython::init();
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* *
|
||||
* Copyright (c) WandererFan (wandererfan@gmail.com) 2016 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
|
@ -24,41 +25,178 @@
|
|||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <Python.h>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopoDS_Edge.hxx>
|
||||
# include <TopoDS_Face.hxx>
|
||||
# include <TopoDS_Wire.hxx>
|
||||
#endif
|
||||
|
||||
#include <Mod/Part/App/TopoShapePy.h>
|
||||
#include <CXX/Extensions.hxx>
|
||||
#include <CXX/Objects.hxx>
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/VectorPy.h>
|
||||
#include <boost/regex.hpp>
|
||||
#include <Base/PyObjectBase.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/Part/App/TopoShapePy.h>
|
||||
#include <Mod/Part/App/TopoShapeEdgePy.h>
|
||||
#include <Mod/Part/App/TopoShapeWirePy.h>
|
||||
|
||||
#include <Mod/Part/App/OCCError.h>
|
||||
|
||||
//using namespace TechDraw;
|
||||
using namespace Part;
|
||||
using namespace std;
|
||||
|
||||
static PyObject *
|
||||
tdPlaceholder(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *pcObjShape;
|
||||
PyObject *pcObjDir=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O!|O!", &(TopoShapePy::Type), &pcObjShape,&(Base::VectorPy::Type), &pcObjDir)) // convert args: Python->C
|
||||
return NULL; // NULL triggers exception
|
||||
|
||||
PY_TRY {
|
||||
TopoShapePy* pShape = static_cast<TopoShapePy*>(pcObjShape);
|
||||
Py::List list;
|
||||
list.append(Py::Object(pShape , true));
|
||||
return Py::new_reference_to(list);
|
||||
|
||||
} PY_CATCH_OCC;
|
||||
#include "EdgeWalker.h"
|
||||
|
||||
namespace TechDraw {
|
||||
//module level static C++ functions go here
|
||||
}
|
||||
|
||||
/* registration table */
|
||||
struct PyMethodDef TechDraw_methods[] = {
|
||||
{"tdPlaceholder" ,tdPlaceholder ,METH_VARARGS,
|
||||
"[n/a] = tdPlaceholder(n/a) -- Temporary hack."},
|
||||
{NULL, NULL} /* end of table marker */
|
||||
};
|
||||
using Part::TopoShape;
|
||||
using Part::TopoShapePy;
|
||||
using Part::TopoShapeEdgePy;
|
||||
using Part::TopoShapeWirePy;
|
||||
|
||||
namespace TechDraw {
|
||||
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("TechDraw")
|
||||
{
|
||||
add_varargs_method("edgeWalker",&Module::edgeWalker,
|
||||
"[wires] = edgeWalker(edgePile,inclBiggest) -- Planar graph traversal finds wires in edge pile."
|
||||
);
|
||||
add_varargs_method("findOuterWire",&Module::findOuterWire,
|
||||
"wire = findOuterWire(edgeList) -- Planar graph traversal finds OuterWire in edge pile."
|
||||
);
|
||||
initialize("This is a module for making drawings"); // register with Python
|
||||
}
|
||||
virtual ~Module() {}
|
||||
|
||||
private:
|
||||
virtual Py::Object invoke_method_varargs(void *method_def, const Py::Tuple &args)
|
||||
{
|
||||
try {
|
||||
return Py::ExtensionModule<Module>::invoke_method_varargs(method_def, args);
|
||||
}
|
||||
catch (const Standard_Failure &e) {
|
||||
std::string str;
|
||||
Standard_CString msg = e.GetMessageString();
|
||||
str += typeid(e).name();
|
||||
str += " ";
|
||||
if (msg) {str += msg;}
|
||||
else {str += "No OCCT Exception Message";}
|
||||
Base::Console().Error("%s\n", str.c_str());
|
||||
throw Py::Exception(Part::PartExceptionOCCError, str);
|
||||
}
|
||||
catch (const Base::Exception &e) {
|
||||
std::string str;
|
||||
str += "FreeCAD exception thrown (";
|
||||
str += e.what();
|
||||
str += ")";
|
||||
e.ReportException();
|
||||
throw Py::RuntimeError(str);
|
||||
}
|
||||
catch (const std::exception &e) {
|
||||
std::string str;
|
||||
str += "C++ exception thrown (";
|
||||
str += e.what();
|
||||
str += ")";
|
||||
Base::Console().Error("%s\n", str.c_str());
|
||||
throw Py::RuntimeError(str);
|
||||
}
|
||||
}
|
||||
|
||||
Py::Object edgeWalker(const Py::Tuple& args)
|
||||
{
|
||||
PyObject *pcObj;
|
||||
PyObject *inclBig = Py_True;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O|O", &pcObj,&inclBig)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Edge> edgeList;
|
||||
|
||||
try {
|
||||
Py::Sequence list(pcObj);
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapeEdgePy::Type))) {
|
||||
const TopoDS_Shape& sh = static_cast<TopoShapePy*>((*it).ptr())->
|
||||
getTopoShapePtr()->getShape();
|
||||
const TopoDS_Edge e = TopoDS::Edge(sh);
|
||||
edgeList.push_back(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Py::Exception(Part::PartExceptionOCCError, e->GetMessageString());
|
||||
}
|
||||
|
||||
bool biggie;
|
||||
if (inclBig == Py_True) {
|
||||
biggie = true;
|
||||
} else {
|
||||
biggie = false;
|
||||
}
|
||||
PyObject* result = PyList_New(0);
|
||||
|
||||
EdgeWalker ew;
|
||||
ew.loadEdges(edgeList);
|
||||
ew.perform();
|
||||
std::vector<TopoDS_Wire> rw = ew.getResultWires();
|
||||
std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(rw,biggie); //false==>do not include biggest wires
|
||||
for (auto& w:sortedWires) {
|
||||
PyList_Append(result,new TopoShapeWirePy(new TopoShape(w)));
|
||||
}
|
||||
|
||||
return Py::asObject(result);
|
||||
}
|
||||
|
||||
Py::Object findOuterWire(const Py::Tuple& args)
|
||||
{
|
||||
PyObject *pcObj;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &pcObj)) {
|
||||
throw Py::Exception();
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Edge> edgeList;
|
||||
|
||||
try {
|
||||
Py::Sequence list(pcObj);
|
||||
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
|
||||
if (PyObject_TypeCheck((*it).ptr(), &(Part::TopoShapeEdgePy::Type))) {
|
||||
const TopoDS_Shape& sh = static_cast<TopoShapePy*>((*it).ptr())->
|
||||
getTopoShapePtr()->getShape();
|
||||
const TopoDS_Edge e = TopoDS::Edge(sh);
|
||||
edgeList.push_back(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
Handle_Standard_Failure e = Standard_Failure::Caught();
|
||||
throw Py::Exception(Part::PartExceptionOCCError, e->GetMessageString());
|
||||
}
|
||||
|
||||
PyObject* result = PyList_New(0);
|
||||
|
||||
EdgeWalker ew;
|
||||
ew.loadEdges(edgeList);
|
||||
ew.perform();
|
||||
std::vector<TopoDS_Wire> rw = ew.getResultWires();
|
||||
std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(rw,true);
|
||||
for (auto& w:sortedWires) {
|
||||
PyList_Append(result,new TopoShapeWirePy(new TopoShape(w)));
|
||||
}
|
||||
PyObject* outerWire = PyList_GetItem(result, 0);
|
||||
return Py::asObject(outerWire);
|
||||
}
|
||||
};
|
||||
|
||||
PyObject* initModule()
|
||||
{
|
||||
return (new Module)->module().ptr();
|
||||
}
|
||||
|
||||
} // namespace TechDraw
|
||||
|
|
|
@ -32,6 +32,11 @@
|
|||
# include <QString>
|
||||
# include <QStringList>
|
||||
# include <QRegExp>
|
||||
|
||||
//#include <TopoDS_Vertex.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Precision.hxx>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
|
@ -93,3 +98,14 @@ std::string DrawUtil::makeGeomName(std::string geomType, int index)
|
|||
return newName.str();
|
||||
}
|
||||
|
||||
|
||||
bool DrawUtil::isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2)
|
||||
{
|
||||
bool result = false;
|
||||
gp_Pnt p1 = BRep_Tool::Pnt(v1);
|
||||
gp_Pnt p2 = BRep_Tool::Pnt(v2);
|
||||
if (p1.IsEqual(p2,Precision::Confusion())) {
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define _DrawUtil_h_
|
||||
|
||||
#include <string>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
|
@ -34,6 +35,7 @@ class TechDrawExport DrawUtil {
|
|||
static int getIndexFromName(std::string geomName);
|
||||
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);
|
||||
};
|
||||
|
||||
} //end namespace TechDraw
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,168 +1,159 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2007 *
|
||||
* Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _DrawViewPart_h_
|
||||
#define _DrawViewPart_h_
|
||||
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include "DrawView.h"
|
||||
#include <App/FeaturePython.h>
|
||||
|
||||
#include <Base/BoundBox.h>
|
||||
|
||||
class gp_Pnt;
|
||||
|
||||
namespace TechDrawGeometry
|
||||
{
|
||||
class GeometryObject;
|
||||
class Vertex;
|
||||
class BaseGeom;
|
||||
class Face;
|
||||
}
|
||||
|
||||
namespace TechDraw {
|
||||
class DrawHatch;
|
||||
struct WalkerEdge;
|
||||
}
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
class DrawViewSection;
|
||||
|
||||
class TechDrawExport DrawViewPart : public DrawView
|
||||
{
|
||||
PROPERTY_HEADER(TechDraw::DrawViewPart);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
DrawViewPart(void);
|
||||
virtual ~DrawViewPart();
|
||||
|
||||
App::PropertyLink Source; //Part Feature
|
||||
App::PropertyVector Direction; //TODO: Rename to YAxisDirection or whatever this actually is (ProjectionDirection)
|
||||
App::PropertyVector XAxisDirection;
|
||||
App::PropertyBool ShowHiddenLines;
|
||||
App::PropertyBool ShowSmoothLines;
|
||||
App::PropertyBool ShowSeamLines;
|
||||
App::PropertyFloat LineWidth;
|
||||
App::PropertyFloat HiddenWidth;
|
||||
App::PropertyBool ShowCenters;
|
||||
App::PropertyFloat CenterScale;
|
||||
App::PropertyFloatConstraint Tolerance;
|
||||
App::PropertyBool HorizCenterLine;
|
||||
App::PropertyBool VertCenterLine;
|
||||
|
||||
App::PropertyBool ShowSectionLine;
|
||||
App::PropertyBool HorizSectionLine; //true(horiz)/false(vert)
|
||||
App::PropertyBool ArrowUpSection; //true(up/right)/false(down/left)
|
||||
App::PropertyString SymbolSection;
|
||||
|
||||
|
||||
std::vector<TechDraw::DrawHatch*> getHatches(void) const;
|
||||
|
||||
//TODO: are there use-cases for Python access to TechDrawGeometry???
|
||||
|
||||
const std::vector<TechDrawGeometry::Vertex *> & getVertexGeometry() const;
|
||||
const std::vector<TechDrawGeometry::BaseGeom *> & getEdgeGeometry() const;
|
||||
const std::vector<TechDrawGeometry::Face *> & getFaceGeometry() const;
|
||||
bool hasGeometry(void) const;
|
||||
|
||||
TechDrawGeometry::BaseGeom* getProjEdgeByIndex(int idx) const; //get existing geom for edge idx in projection
|
||||
TechDrawGeometry::Vertex* getProjVertexByIndex(int idx) const; //get existing geom for vertex idx in projection
|
||||
std::vector<TechDrawGeometry::BaseGeom*> getProjFaceByIndex(int idx) const; //get edges for face idx in projection
|
||||
virtual Base::BoundBox3d getBoundingBox() const;
|
||||
double getBoxX(void) const;
|
||||
double getBoxY(void) const;
|
||||
virtual QRectF getRect() const;
|
||||
virtual DrawViewSection* getSectionRef() const; //is there a ViewSection based on this ViewPart?
|
||||
Base::Vector3d getUDir(void) {return uDir;} //paperspace X
|
||||
Base::Vector3d getVDir(void) {return vDir;} //paperspace Y
|
||||
Base::Vector3d getWDir(void) {return wDir;} //paperspace Z
|
||||
|
||||
short mustExecute() const;
|
||||
|
||||
/** @name methods overide Feature */
|
||||
//@{
|
||||
/// recalculate the Feature
|
||||
virtual App::DocumentObjectExecReturn *execute(void);
|
||||
//@}
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
virtual const char* getViewProviderName(void) const {
|
||||
return "TechDrawGui::ViewProviderViewPart";
|
||||
}
|
||||
//return PyObject as DrawViewPartPy
|
||||
virtual PyObject *getPyObject(void);
|
||||
|
||||
void dumpVertexes(const char* text, const TopoDS_Shape& s);
|
||||
void dumpEdge(char* label, int i, TopoDS_Edge e);
|
||||
void dump1Vertex(const char* label, const TopoDS_Vertex& v);
|
||||
void countFaces(const char* label, const TopoDS_Shape& s);
|
||||
void countWires(const char* label, const TopoDS_Shape& s);
|
||||
void countEdges(const char* label, const TopoDS_Shape& s);
|
||||
Base::Vector3d getValidXDir() const;
|
||||
Base::Vector3d projectPoint(Base::Vector3d pt) const;
|
||||
|
||||
protected:
|
||||
TechDrawGeometry::GeometryObject *geometryObject;
|
||||
Base::BoundBox3d bbox;
|
||||
|
||||
void onChanged(const App::Property* prop);
|
||||
void buildGeometryObject(TopoDS_Shape shape, gp_Pnt& center);
|
||||
void extractFaces();
|
||||
std::vector<TopoDS_Wire> sortWiresBySize(std::vector<TopoDS_Wire>& w, bool reverse = false);
|
||||
class wireCompare;
|
||||
|
||||
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);
|
||||
bool isSamePoint(TopoDS_Vertex v1, TopoDS_Vertex v2);
|
||||
int findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &uniqueVert);
|
||||
std::vector<TopoDS_Vertex> makeUniqueVList(std::vector<TopoDS_Edge> edges);
|
||||
std::vector<WalkerEdge> makeWalkerEdges(std::vector<TopoDS_Edge> edges,
|
||||
std::vector<TopoDS_Vertex> verts);
|
||||
TopoDS_Wire makeCleanWire(std::vector<TopoDS_Edge> edges, double tol = 0.10);
|
||||
|
||||
//Projection parameter space
|
||||
void saveParamSpace(Base::Vector3d direction,
|
||||
Base::Vector3d xAxis);
|
||||
Base::Vector3d uDir; //paperspace X
|
||||
Base::Vector3d vDir; //paperspace Y
|
||||
Base::Vector3d wDir; //paperspace Z
|
||||
Base::Vector3d shapeCentroid;
|
||||
|
||||
private:
|
||||
static App::PropertyFloatConstraint::Constraints floatRange;
|
||||
|
||||
};
|
||||
|
||||
typedef App::FeaturePythonT<DrawViewPart> DrawViewPartPython;
|
||||
|
||||
} //namespace TechDraw
|
||||
|
||||
#endif // #ifndef _DrawViewPart_h_
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2007 *
|
||||
* Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 *
|
||||
* Copyright (c) WandererFan (wandererfan@gmail.com) 2016 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _DrawViewPart_h_
|
||||
#define _DrawViewPart_h_
|
||||
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include "DrawView.h"
|
||||
#include <App/FeaturePython.h>
|
||||
|
||||
#include <Base/BoundBox.h>
|
||||
|
||||
class gp_Pnt;
|
||||
|
||||
namespace TechDrawGeometry
|
||||
{
|
||||
class GeometryObject;
|
||||
class Vertex;
|
||||
class BaseGeom;
|
||||
class Face;
|
||||
}
|
||||
|
||||
namespace TechDraw {
|
||||
class DrawHatch;
|
||||
}
|
||||
|
||||
namespace TechDraw
|
||||
{
|
||||
class DrawViewSection;
|
||||
|
||||
class TechDrawExport DrawViewPart : public DrawView
|
||||
{
|
||||
PROPERTY_HEADER(TechDraw::DrawViewPart);
|
||||
|
||||
public:
|
||||
DrawViewPart(void);
|
||||
virtual ~DrawViewPart();
|
||||
|
||||
App::PropertyLink Source; //Part Feature
|
||||
App::PropertyVector Direction; //TODO: Rename to YAxisDirection or whatever this actually is (ProjectionDirection)
|
||||
App::PropertyVector XAxisDirection;
|
||||
App::PropertyBool ShowHiddenLines;
|
||||
App::PropertyBool ShowSmoothLines;
|
||||
App::PropertyBool ShowSeamLines;
|
||||
App::PropertyFloat LineWidth;
|
||||
App::PropertyFloat HiddenWidth;
|
||||
App::PropertyBool ShowCenters;
|
||||
App::PropertyFloat CenterScale;
|
||||
App::PropertyFloatConstraint Tolerance;
|
||||
App::PropertyBool HorizCenterLine;
|
||||
App::PropertyBool VertCenterLine;
|
||||
|
||||
App::PropertyBool ShowSectionLine;
|
||||
App::PropertyBool HorizSectionLine; //true(horiz)/false(vert)
|
||||
App::PropertyBool ArrowUpSection; //true(up/right)/false(down/left)
|
||||
App::PropertyString SymbolSection;
|
||||
|
||||
|
||||
std::vector<TechDraw::DrawHatch*> getHatches(void) const;
|
||||
|
||||
//TODO: are there use-cases for Python access to TechDrawGeometry???
|
||||
|
||||
const std::vector<TechDrawGeometry::Vertex *> & getVertexGeometry() const;
|
||||
const std::vector<TechDrawGeometry::BaseGeom *> & getEdgeGeometry() const;
|
||||
const std::vector<TechDrawGeometry::Face *> & getFaceGeometry() const;
|
||||
bool hasGeometry(void) const;
|
||||
|
||||
TechDrawGeometry::BaseGeom* getProjEdgeByIndex(int idx) const; //get existing geom for edge idx in projection
|
||||
TechDrawGeometry::Vertex* getProjVertexByIndex(int idx) const; //get existing geom for vertex idx in projection
|
||||
std::vector<TechDrawGeometry::BaseGeom*> getProjFaceByIndex(int idx) const; //get edges for face idx in projection
|
||||
virtual Base::BoundBox3d getBoundingBox() const;
|
||||
double getBoxX(void) const;
|
||||
double getBoxY(void) const;
|
||||
virtual QRectF getRect() const;
|
||||
virtual DrawViewSection* getSectionRef() const; //is there a ViewSection based on this ViewPart?
|
||||
Base::Vector3d getUDir(void) {return uDir;} //paperspace X
|
||||
Base::Vector3d getVDir(void) {return vDir;} //paperspace Y
|
||||
Base::Vector3d getWDir(void) {return wDir;} //paperspace Z
|
||||
|
||||
short mustExecute() const;
|
||||
|
||||
/** @name methods overide Feature */
|
||||
//@{
|
||||
/// recalculate the Feature
|
||||
virtual App::DocumentObjectExecReturn *execute(void);
|
||||
//@}
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
virtual const char* getViewProviderName(void) const {
|
||||
return "TechDrawGui::ViewProviderViewPart";
|
||||
}
|
||||
//return PyObject as DrawViewPartPy
|
||||
virtual PyObject *getPyObject(void);
|
||||
|
||||
void dumpVertexes(const char* text, const TopoDS_Shape& s);
|
||||
void dumpEdge(char* label, int i, TopoDS_Edge e);
|
||||
void dump1Vertex(const char* label, const TopoDS_Vertex& v);
|
||||
void countFaces(const char* label, const TopoDS_Shape& s);
|
||||
void countWires(const char* label, const TopoDS_Shape& s);
|
||||
void countEdges(const char* label, const TopoDS_Shape& s);
|
||||
Base::Vector3d getValidXDir() const;
|
||||
Base::Vector3d projectPoint(Base::Vector3d pt) const;
|
||||
|
||||
protected:
|
||||
TechDrawGeometry::GeometryObject *geometryObject;
|
||||
Base::BoundBox3d bbox;
|
||||
|
||||
void onChanged(const App::Property* prop);
|
||||
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);
|
||||
|
||||
//Projection parameter space
|
||||
void saveParamSpace(Base::Vector3d direction,
|
||||
Base::Vector3d xAxis);
|
||||
Base::Vector3d uDir; //paperspace X
|
||||
Base::Vector3d vDir; //paperspace Y
|
||||
Base::Vector3d wDir; //paperspace Z
|
||||
Base::Vector3d shapeCentroid;
|
||||
|
||||
private:
|
||||
static App::PropertyFloatConstraint::Constraints floatRange;
|
||||
|
||||
};
|
||||
|
||||
typedef App::FeaturePythonT<DrawViewPart> DrawViewPartPython;
|
||||
|
||||
} //namespace TechDraw
|
||||
|
||||
#endif // #ifndef _DrawViewPart_h_
|
||||
|
|
|
@ -1,466 +1,476 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 *
|
||||
* Copyright (c) WandererFan (wandererfan@gmail.com) 2016 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <HLRBRep_Algo.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_HLRToShape.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Material.h>
|
||||
#include <Base/BoundBox.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "GeometryObject.h"
|
||||
#include "EdgeWalker.h"
|
||||
#include "DrawViewSection.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
using namespace std;
|
||||
|
||||
//===========================================================================
|
||||
// DrawViewSection
|
||||
//===========================================================================
|
||||
|
||||
PROPERTY_SOURCE(TechDraw::DrawViewSection, TechDraw::DrawViewPart)
|
||||
|
||||
DrawViewSection::DrawViewSection()
|
||||
{
|
||||
static const char *sgroup = "Section";
|
||||
static const char *lgroup = "Line";
|
||||
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
|
||||
App::Color fcColor = App::Color((uint32_t) hGrp->GetUnsigned("CutSurfaceColor", 0xC8C8C800));
|
||||
|
||||
ADD_PROPERTY_TYPE(SectionNormal ,(0,0,1.0) ,sgroup,App::Prop_None,"Section Plane normal direction");
|
||||
ADD_PROPERTY_TYPE(SectionOrigin ,(0,0,0) ,sgroup,App::Prop_None,"Section Plane Origin");
|
||||
ADD_PROPERTY_TYPE(ShowCutSurface ,(true),sgroup,App::Prop_None,"Show the cut surface");
|
||||
ADD_PROPERTY_TYPE(CutSurfaceColor,(fcColor),sgroup,App::Prop_None,"The color to shade the cut surface");
|
||||
|
||||
ADD_PROPERTY_TYPE(BaseView ,(0),lgroup,App::Prop_None,"2D View with SectionLine");
|
||||
|
||||
geometryObject = new TechDrawGeometry::GeometryObject();
|
||||
}
|
||||
|
||||
DrawViewSection::~DrawViewSection()
|
||||
{
|
||||
}
|
||||
|
||||
short DrawViewSection::mustExecute() const
|
||||
{
|
||||
// If Tolerance Property is touched
|
||||
if(SectionNormal.isTouched() ||
|
||||
SectionOrigin.isTouched() ||
|
||||
ShowCutSurface.isTouched() ||
|
||||
CutSurfaceColor.isTouched() )
|
||||
return 1;
|
||||
|
||||
return TechDraw::DrawViewPart::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *DrawViewSection::execute(void)
|
||||
{
|
||||
App::DocumentObject* link = Source.getValue();
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (!link || !base) {
|
||||
Base::Console().Log("INFO - DVS::execute - No Source or Link - creation?\n");
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
return new App::DocumentObjectExecReturn("Source object is not a Part object");
|
||||
if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()))
|
||||
return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");
|
||||
|
||||
const Part::TopoShape &partTopo = static_cast<Part::Feature*>(link)->Shape.getShape();
|
||||
const TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(base);
|
||||
|
||||
if (partTopo.getShape().IsNull())
|
||||
return new App::DocumentObjectExecReturn("Linked shape object is empty");
|
||||
|
||||
gp_Pln pln = getSectionPlane();
|
||||
// Get the Axis Directions for the Plane to transform UV components again
|
||||
gp_XYZ xAxis = pln.XAxis().Direction().XYZ();
|
||||
gp_XYZ yAxis = pln.YAxis().Direction().XYZ();
|
||||
gp_XYZ origin = pln.Location().XYZ();
|
||||
gp_Dir plnNormal = pln.Axis().Direction().XYZ();
|
||||
|
||||
Base::BoundBox3d bb = partTopo.getBoundBox();
|
||||
|
||||
Base::Vector3d tmp1 = SectionOrigin.getValue();
|
||||
Base::Vector3d plnPnt(tmp1.x, tmp1.y, tmp1.z);
|
||||
//Base::Vector3d tmp2 = SectionNormal.getValue();
|
||||
Base::Vector3d plnNorm(plnNormal.X(), plnNormal.Y(), plnNormal.Z());
|
||||
|
||||
// if(!bb.IsCutPlane(plnPnt, plnNorm)) { //this test doesn't work if plane is coincident with bb!
|
||||
if(!isReallyInBox(plnPnt, bb)) {
|
||||
Base::Console().Warning("DVS: Section Plane doesn't intersect part in %s\n",getNameInDocument());
|
||||
Base::Console().Warning("DVS: Using center of bounding box.\n");
|
||||
plnPnt = bb.GetCenter();
|
||||
SectionOrigin.setValue(plnPnt);
|
||||
}
|
||||
|
||||
// Gather the corner points of bbox
|
||||
std::vector<Base::Vector3d> pnts;
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MinY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MinY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MaxY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MaxY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MinY,bb.MaxZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MinY,bb.MaxZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MaxY,bb.MaxZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MaxY,bb.MaxZ));
|
||||
|
||||
double uMax = 0, vMax = 0, wMax = 0., dMax = 0;
|
||||
for(std::vector<Base::Vector3d>::const_iterator it = pnts.begin(); it != pnts.end(); ++it) {
|
||||
// Project each bounding box point onto projection plane and find largest u,v,w values
|
||||
Base::Vector3d pnt = (*it);
|
||||
pnt.ProjectToPlane(plnPnt, plnNorm);
|
||||
uMax = std::max(uMax, std::abs(plnPnt.x - pnt.x)); //one will be zero
|
||||
vMax = std::max(vMax, std::abs(plnPnt.y - pnt.y));
|
||||
wMax = std::max(wMax, std::abs(plnPnt.z - pnt.z));
|
||||
|
||||
//dMax is the bounding box point furthest away from plane. used for determining extrusion length
|
||||
double dist = (*it).DistanceToPlane(plnPnt, plnNorm);
|
||||
dMax = std::max(dMax, dist);
|
||||
}
|
||||
|
||||
//use largest of u,v,w to make cutting face that covers whole shape
|
||||
double maxParm = std::max(uMax,vMax);
|
||||
maxParm = std::max(maxParm,wMax);
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
gp_Pnt pn1(origin + xAxis * maxParm + yAxis * maxParm);
|
||||
gp_Pnt pn2(origin + xAxis * maxParm + yAxis * -maxParm);
|
||||
gp_Pnt pn3(origin + xAxis * -maxParm + yAxis * -maxParm);
|
||||
gp_Pnt pn4(origin + xAxis * -maxParm + yAxis * +maxParm);
|
||||
|
||||
mkPoly.Add(pn1);
|
||||
mkPoly.Add(pn2);
|
||||
mkPoly.Add(pn3);
|
||||
mkPoly.Add(pn4);
|
||||
mkPoly.Close();
|
||||
|
||||
// Make the extrusion face
|
||||
BRepBuilderAPI_MakeFace mkFace(mkPoly.Wire());
|
||||
TopoDS_Face aProjFace = mkFace.Face();
|
||||
if(aProjFace.IsNull())
|
||||
return new App::DocumentObjectExecReturn("DrawViewSection - Projected face is NULL");
|
||||
TopoDS_Shape prism = BRepPrimAPI_MakePrism(aProjFace, dMax * gp_Vec(pln.Axis().Direction()), false, true).Shape();
|
||||
|
||||
// We need to copy the shape to not modify the BRepstructure
|
||||
BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape());
|
||||
TopoDS_Shape myShape = BuilderCopy.Shape();
|
||||
|
||||
BRepAlgoAPI_Cut mkCut(myShape, prism);
|
||||
if (!mkCut.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Section cut has failed");
|
||||
|
||||
TopoDS_Shape rawShape = mkCut.Shape();
|
||||
|
||||
geometryObject->setTolerance(Tolerance.getValue());
|
||||
geometryObject->setScale(Scale.getValue());
|
||||
try {
|
||||
gp_Pnt inputCenter = TechDrawGeometry::findCentroid(rawShape,
|
||||
Direction.getValue(),
|
||||
getValidXDir());
|
||||
TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape,
|
||||
inputCenter,
|
||||
Scale.getValue());
|
||||
buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism
|
||||
|
||||
#if MOD_TECHDRAW_HANDLE_FACES
|
||||
extractFaces();
|
||||
#endif //#if MOD_TECHDRAW_HANDLE_FACES
|
||||
|
||||
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 (; expl.More(); expl.Next()) {
|
||||
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();
|
||||
return new App::DocumentObjectExecReturn(std::string("DVS building Section shape failed: ") +
|
||||
std::string(e1->GetMessageString()));
|
||||
}
|
||||
|
||||
std::string symbol = dvp->SymbolSection.getValue();
|
||||
std::string symbolText = "Section " + symbol + "-" + symbol;
|
||||
if (symbolText.compare(Label.getValue())) {
|
||||
Label.setValue(symbolText.c_str());
|
||||
}
|
||||
|
||||
|
||||
touch();
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
gp_Pln DrawViewSection::getSectionPlane() const
|
||||
{
|
||||
Base::Vector3d plnPnt = SectionOrigin.getValue();
|
||||
Base::Vector3d plnNorm = SectionNormal.getValue();
|
||||
|
||||
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 shape giving a collection of planar faces
|
||||
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
|
||||
{
|
||||
TopoDS_Compound result;
|
||||
if(shape.IsNull()){
|
||||
Base::Console().Log("DrawViewSection::getSectionSurface - Sectional View shape is Empty\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
gp_Pln plnSection = getSectionPlane();
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(result);
|
||||
|
||||
TopExp_Explorer expFaces(shape, TopAbs_FACE);
|
||||
int i;
|
||||
int dbAdded = 0;
|
||||
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 plnFace = adapt.Plane();
|
||||
|
||||
if(plnSection.Contains(plnFace.Location(), Precision::Confusion()) &&
|
||||
plnFace.Axis().IsParallel(plnSection.Axis(), Precision::Angular())) {
|
||||
dbAdded++;
|
||||
builder.Add(result, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//! get display geometry for Section faces
|
||||
std::vector<TechDrawGeometry::Face*> DrawViewSection::getFaceGeometry()
|
||||
{
|
||||
std::vector<TechDrawGeometry::Face*> result;
|
||||
TopoDS_Compound c = sectionFaces;
|
||||
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());
|
||||
//dumpEdge("edge",edgeCount,edge);
|
||||
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");
|
||||
}
|
||||
|
||||
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::projectFace - hard edge: %d is NULL\n",i);
|
||||
continue;
|
||||
}
|
||||
faceEdges.push_back(edge);
|
||||
}
|
||||
//if edge is both hard & outline, it will be duplicated? are hard edges enough?
|
||||
// TopExp_Explorer expl2(outEdges, TopAbs_EDGE);
|
||||
// for (i = 1 ; expl2.More(); expl2.Next(),i++) {
|
||||
// const TopoDS_Edge& edge = TopoDS::Edge(expl2.Current());
|
||||
// if (edge.IsNull()) {
|
||||
// Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i);
|
||||
// continue;
|
||||
// }
|
||||
// bool addEdge = true;
|
||||
// //is edge already in faceEdges? maybe need to use explorer for this for IsSame to work?
|
||||
// for (auto& e:faceEdges) {
|
||||
// if (e.IsPartner(edge)) {
|
||||
// addEdge = false;
|
||||
// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 1\n");
|
||||
// }
|
||||
// }
|
||||
// expl.ReInit();
|
||||
// for (; expl.More(); expl.Next()){
|
||||
// const TopoDS_Edge& eHard = TopoDS::Edge(expl.Current());
|
||||
// if (eHard.IsPartner(edge)) {
|
||||
// addEdge = false;
|
||||
// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 2\n");
|
||||
// }
|
||||
// }
|
||||
// if (addEdge) {
|
||||
// faceEdges.push_back(edge);
|
||||
// }
|
||||
// }
|
||||
|
||||
std::vector<TopoDS_Vertex> uniqueVert = makeUniqueVList(faceEdges);
|
||||
std::vector<WalkerEdge> walkerEdges = makeWalkerEdges(faceEdges,uniqueVert);
|
||||
|
||||
EdgeWalker ew;
|
||||
ew.setSize(uniqueVert.size());
|
||||
ew.loadEdges(walkerEdges);
|
||||
ew.perform();
|
||||
facelist result = ew.getResult();
|
||||
result = TechDraw::EdgeWalker::removeDuplicateFaces(result);
|
||||
|
||||
facelist::iterator iFace = result.begin();
|
||||
std::vector<TopoDS_Wire> fw;
|
||||
int dbi = 0;
|
||||
for (;iFace != result.end(); iFace++,dbi++) {
|
||||
edgelist::iterator iEdge = (*iFace).begin();
|
||||
std::vector<TopoDS_Edge> fe;
|
||||
for (;iEdge != (*iFace).end(); iEdge++) {
|
||||
fe.push_back(faceEdges.at((*iEdge).idx));
|
||||
}
|
||||
TopoDS_Wire w = makeCleanWire(fe);
|
||||
fw.push_back(w);
|
||||
}
|
||||
|
||||
TopoDS_Face projectedFace;
|
||||
if (!fw.empty()) {
|
||||
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(fw);
|
||||
if (sortedWires.empty()) {
|
||||
return projectedFace;
|
||||
}
|
||||
//TODO: should have the same size checking logic as DVP?
|
||||
//remove the largest wire (OuterWire of graph) ??? but duplicates have been removed? only do this if a mosaic?
|
||||
//sortedWires.erase(sortedWires.begin());
|
||||
|
||||
BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes?
|
||||
std::vector<TopoDS_Wire>::iterator itWire = ++sortedWires.begin(); //starting with second face
|
||||
for (; itWire != sortedWires.end(); itWire++) {
|
||||
mkFace.Add(*itWire);
|
||||
}
|
||||
projectedFace = mkFace.Face();
|
||||
}
|
||||
return projectedFace;
|
||||
}
|
||||
|
||||
//this should really be in BoundBox.h
|
||||
bool DrawViewSection::isReallyInBox (const Base::Vector3d v, const Base::BoundBox3d bb) const
|
||||
{
|
||||
if (v.x <= bb.MinX || v.x >= bb.MaxX)
|
||||
return false;
|
||||
if (v.y <= bb.MinY || v.y >= bb.MaxY)
|
||||
return false;
|
||||
if (v.z <= bb.MinZ || v.z >= bb.MaxZ)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Python Drawing feature ---------------------------------------------------------
|
||||
|
||||
namespace App {
|
||||
/// @cond DOXERR
|
||||
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewSectionPython, TechDraw::DrawViewSection)
|
||||
template<> const char* TechDraw::DrawViewSectionPython::getViewProviderName(void) const {
|
||||
return "TechDrawGui::ViewProviderDrawingView";
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
// explicit template instantiation
|
||||
template class TechDrawExport FeaturePythonT<TechDraw::DrawViewSection>;
|
||||
}
|
||||
/***************************************************************************
|
||||
* Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 *
|
||||
* Copyright (c) Luke Parry (l.parry@warwick.ac.uk) 2013 *
|
||||
* Copyright (c) WandererFan (wandererfan@gmail.com) 2016 *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <sstream>
|
||||
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <HLRBRep_Algo.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_HLRToShape.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Material.h>
|
||||
#include <Base/BoundBox.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "GeometryObject.h"
|
||||
#include "EdgeWalker.h"
|
||||
#include "DrawViewSection.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
using namespace std;
|
||||
|
||||
//===========================================================================
|
||||
// DrawViewSection
|
||||
//===========================================================================
|
||||
|
||||
PROPERTY_SOURCE(TechDraw::DrawViewSection, TechDraw::DrawViewPart)
|
||||
|
||||
DrawViewSection::DrawViewSection()
|
||||
{
|
||||
static const char *sgroup = "Section";
|
||||
static const char *lgroup = "Line";
|
||||
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
|
||||
App::Color fcColor = App::Color((uint32_t) hGrp->GetUnsigned("CutSurfaceColor", 0xC8C8C800));
|
||||
|
||||
ADD_PROPERTY_TYPE(SectionNormal ,(0,0,1.0) ,sgroup,App::Prop_None,"Section Plane normal direction"); //direction of extrusion of cutting prism
|
||||
ADD_PROPERTY_TYPE(SectionOrigin ,(0,0,0) ,sgroup,App::Prop_None,"Section Plane Origin");
|
||||
ADD_PROPERTY_TYPE(ShowCutSurface ,(true),sgroup,App::Prop_None,"Show the cut surface");
|
||||
ADD_PROPERTY_TYPE(CutSurfaceColor,(fcColor),sgroup,App::Prop_None,"The color to shade the cut surface");
|
||||
|
||||
ADD_PROPERTY_TYPE(BaseView ,(0),lgroup,App::Prop_None,"2D View with SectionLine");
|
||||
|
||||
geometryObject = new TechDrawGeometry::GeometryObject();
|
||||
}
|
||||
|
||||
DrawViewSection::~DrawViewSection()
|
||||
{
|
||||
}
|
||||
|
||||
short DrawViewSection::mustExecute() const
|
||||
{
|
||||
// If Tolerance Property is touched
|
||||
if(SectionNormal.isTouched() ||
|
||||
SectionOrigin.isTouched() ||
|
||||
ShowCutSurface.isTouched() ||
|
||||
CutSurfaceColor.isTouched() )
|
||||
return 1;
|
||||
|
||||
return TechDraw::DrawViewPart::mustExecute();
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn *DrawViewSection::execute(void)
|
||||
{
|
||||
App::DocumentObject* link = Source.getValue();
|
||||
App::DocumentObject* base = BaseView.getValue();
|
||||
if (!link || !base) {
|
||||
Base::Console().Log("INFO - DVS::execute - No Source or Link - creation?\n");
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
return new App::DocumentObjectExecReturn("Source object is not a Part object");
|
||||
if (!base->getTypeId().isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId()))
|
||||
return new App::DocumentObjectExecReturn("BaseView object is not a DrawViewPart object");
|
||||
|
||||
const Part::TopoShape &partTopo = static_cast<Part::Feature*>(link)->Shape.getShape();
|
||||
const TechDraw::DrawViewPart* dvp = static_cast<TechDraw::DrawViewPart*>(base);
|
||||
|
||||
if (partTopo.getShape().IsNull())
|
||||
return new App::DocumentObjectExecReturn("Linked shape object is empty");
|
||||
|
||||
gp_Pln pln = getSectionPlane();
|
||||
// Get the Axis Directions for the Plane to transform UV components again
|
||||
gp_XYZ xAxis = pln.XAxis().Direction().XYZ();
|
||||
gp_XYZ yAxis = pln.YAxis().Direction().XYZ();
|
||||
gp_XYZ origin = pln.Location().XYZ();
|
||||
gp_Dir plnNormal = pln.Axis().Direction().XYZ();
|
||||
|
||||
Base::BoundBox3d bb = partTopo.getBoundBox();
|
||||
|
||||
Base::Vector3d tmp1 = SectionOrigin.getValue();
|
||||
Base::Vector3d plnPnt(tmp1.x, tmp1.y, tmp1.z);
|
||||
//Base::Vector3d tmp2 = SectionNormal.getValue();
|
||||
Base::Vector3d plnNorm(plnNormal.X(), plnNormal.Y(), plnNormal.Z());
|
||||
|
||||
// if(!bb.IsCutPlane(plnPnt, plnNorm)) { //this test doesn't work if plane is coincident with bb!
|
||||
if(!isReallyInBox(plnPnt, bb)) {
|
||||
Base::Console().Warning("DVS: Section Plane doesn't intersect part in %s\n",getNameInDocument());
|
||||
Base::Console().Warning("DVS: Using center of bounding box.\n");
|
||||
plnPnt = bb.GetCenter();
|
||||
SectionOrigin.setValue(plnPnt);
|
||||
}
|
||||
|
||||
// Gather the corner points of bbox
|
||||
std::vector<Base::Vector3d> pnts;
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MinY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MinY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MaxY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MaxY,bb.MinZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MinY,bb.MaxZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MinY,bb.MaxZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MinX,bb.MaxY,bb.MaxZ));
|
||||
pnts.push_back(Base::Vector3d(bb.MaxX,bb.MaxY,bb.MaxZ));
|
||||
|
||||
double uMax = 0, vMax = 0, wMax = 0., dMax = 0;
|
||||
for(std::vector<Base::Vector3d>::const_iterator it = pnts.begin(); it != pnts.end(); ++it) {
|
||||
// Project each bounding box point onto projection plane and find largest u,v,w values
|
||||
Base::Vector3d pnt = (*it);
|
||||
pnt.ProjectToPlane(plnPnt, plnNorm);
|
||||
uMax = std::max(uMax, std::abs(plnPnt.x - pnt.x)); //one will be zero
|
||||
vMax = std::max(vMax, std::abs(plnPnt.y - pnt.y));
|
||||
wMax = std::max(wMax, std::abs(plnPnt.z - pnt.z));
|
||||
|
||||
//dMax is the bounding box point furthest away from plane. used for determining extrusion length
|
||||
double dist = (*it).DistanceToPlane(plnPnt, plnNorm);
|
||||
dMax = std::max(dMax, dist);
|
||||
}
|
||||
|
||||
//use largest of u,v,w to make cutting face that covers whole shape
|
||||
double maxParm = std::max(uMax,vMax);
|
||||
maxParm = std::max(maxParm,wMax);
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
gp_Pnt pn1(origin + xAxis * maxParm + yAxis * maxParm);
|
||||
gp_Pnt pn2(origin + xAxis * maxParm + yAxis * -maxParm);
|
||||
gp_Pnt pn3(origin + xAxis * -maxParm + yAxis * -maxParm);
|
||||
gp_Pnt pn4(origin + xAxis * -maxParm + yAxis * +maxParm);
|
||||
|
||||
mkPoly.Add(pn1);
|
||||
mkPoly.Add(pn2);
|
||||
mkPoly.Add(pn3);
|
||||
mkPoly.Add(pn4);
|
||||
mkPoly.Close();
|
||||
|
||||
// Make the extrusion face
|
||||
BRepBuilderAPI_MakeFace mkFace(mkPoly.Wire());
|
||||
TopoDS_Face aProjFace = mkFace.Face();
|
||||
if(aProjFace.IsNull())
|
||||
return new App::DocumentObjectExecReturn("DrawViewSection - Projected face is NULL");
|
||||
TopoDS_Shape prism = BRepPrimAPI_MakePrism(aProjFace, dMax * gp_Vec(pln.Axis().Direction()), false, true).Shape();
|
||||
|
||||
// We need to copy the shape to not modify the BRepstructure
|
||||
BRepBuilderAPI_Copy BuilderCopy(partTopo.getShape());
|
||||
TopoDS_Shape myShape = BuilderCopy.Shape();
|
||||
|
||||
BRepAlgoAPI_Cut mkCut(myShape, prism);
|
||||
if (!mkCut.IsDone())
|
||||
return new App::DocumentObjectExecReturn("Section cut has failed");
|
||||
|
||||
TopoDS_Shape rawShape = mkCut.Shape();
|
||||
|
||||
geometryObject->setTolerance(Tolerance.getValue());
|
||||
geometryObject->setScale(Scale.getValue());
|
||||
try {
|
||||
gp_Pnt inputCenter = TechDrawGeometry::findCentroid(rawShape,
|
||||
Direction.getValue(),
|
||||
getValidXDir());
|
||||
TopoDS_Shape mirroredShape = TechDrawGeometry::mirrorShape(rawShape,
|
||||
inputCenter,
|
||||
Scale.getValue());
|
||||
buildGeometryObject(mirroredShape,inputCenter); //this is original shape after cut by section prism
|
||||
|
||||
#if MOD_TECHDRAW_HANDLE_FACES
|
||||
extractFaces();
|
||||
#endif //#if MOD_TECHDRAW_HANDLE_FACES
|
||||
|
||||
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 (; expl.More(); expl.Next()) {
|
||||
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();
|
||||
return new App::DocumentObjectExecReturn(std::string("DVS building Section shape failed: ") +
|
||||
std::string(e1->GetMessageString()));
|
||||
}
|
||||
|
||||
std::string symbol = dvp->SymbolSection.getValue();
|
||||
std::string symbolText = "Section " + symbol + "-" + symbol;
|
||||
if (symbolText.compare(Label.getValue())) {
|
||||
Label.setValue(symbolText.c_str());
|
||||
}
|
||||
|
||||
|
||||
touch();
|
||||
return DrawView::execute();
|
||||
}
|
||||
|
||||
gp_Pln DrawViewSection::getSectionPlane() const
|
||||
{
|
||||
Base::Vector3d plnPnt = SectionOrigin.getValue();
|
||||
Base::Vector3d plnNorm = SectionNormal.getValue();
|
||||
|
||||
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 shape giving a collection of planar faces
|
||||
TopoDS_Compound DrawViewSection::findSectionPlaneIntersections(const TopoDS_Shape& shape)
|
||||
{
|
||||
TopoDS_Compound result;
|
||||
if(shape.IsNull()){
|
||||
Base::Console().Log("DrawViewSection::getSectionSurface - Sectional View shape is Empty\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
gp_Pln plnSection = getSectionPlane();
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(result);
|
||||
|
||||
TopExp_Explorer expFaces(shape, TopAbs_FACE);
|
||||
int i;
|
||||
int dbAdded = 0;
|
||||
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 plnFace = adapt.Plane();
|
||||
|
||||
if(plnSection.Contains(plnFace.Location(), Precision::Confusion()) &&
|
||||
plnFace.Axis().IsParallel(plnSection.Axis(), Precision::Angular())) {
|
||||
dbAdded++;
|
||||
builder.Add(result, face);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//! get display geometry for Section faces
|
||||
std::vector<TechDrawGeometry::Face*> DrawViewSection::getFaceGeometry()
|
||||
{
|
||||
std::vector<TechDrawGeometry::Face*> result;
|
||||
TopoDS_Compound c = sectionFaces;
|
||||
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());
|
||||
//dumpEdge("edge",edgeCount,edge);
|
||||
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 - used for section faces
|
||||
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");
|
||||
}
|
||||
|
||||
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 - DVS::projectFace - hard edge: %d is NULL\n",i);
|
||||
continue;
|
||||
}
|
||||
faceEdges.push_back(edge);
|
||||
}
|
||||
//if edge is both hard & outline, it will be duplicated? are hard edges enough?
|
||||
// TopExp_Explorer expl2(outEdges, TopAbs_EDGE);
|
||||
// for (i = 1 ; expl2.More(); expl2.Next(),i++) {
|
||||
// const TopoDS_Edge& edge = TopoDS::Edge(expl2.Current());
|
||||
// if (edge.IsNull()) {
|
||||
// Base::Console().Log("INFO - GO::projectFace - outline edge: %d is NULL\n",i);
|
||||
// continue;
|
||||
// }
|
||||
// bool addEdge = true;
|
||||
// //is edge already in faceEdges? maybe need to use explorer for this for IsSame to work?
|
||||
// for (auto& e:faceEdges) {
|
||||
// if (e.IsPartner(edge)) {
|
||||
// addEdge = false;
|
||||
// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 1\n");
|
||||
// }
|
||||
// }
|
||||
// expl.ReInit();
|
||||
// for (; expl.More(); expl.Next()){
|
||||
// const TopoDS_Edge& eHard = TopoDS::Edge(expl.Current());
|
||||
// if (eHard.IsPartner(edge)) {
|
||||
// addEdge = false;
|
||||
// Base::Console().Message("TRACE - DVS::projectFace - skipping an edge 2\n");
|
||||
// }
|
||||
// }
|
||||
// if (addEdge) {
|
||||
// faceEdges.push_back(edge);
|
||||
// }
|
||||
// }
|
||||
|
||||
// std::vector<TopoDS_Vertex> uniqueVert = makeUniqueVList(faceEdges);
|
||||
// std::vector<WalkerEdge> walkerEdges = makeWalkerEdges(faceEdges,uniqueVert);
|
||||
|
||||
//recreate the wires for this single face
|
||||
EdgeWalker ew;
|
||||
ew.loadEdges(faceEdges);
|
||||
ew.perform();
|
||||
std::vector<TopoDS_Wire> fw = ew.getResultNoDups();
|
||||
|
||||
// EdgeWalker ew;
|
||||
// ew.setSize(uniqueVert.size());
|
||||
// ew.loadEdges(walkerEdges);
|
||||
// ew.perform();
|
||||
// facelist result = ew.getResult();
|
||||
|
||||
//>>>>>>>>. result = TechDraw::EdgeWalker::removeDuplicateFaces(result);
|
||||
|
||||
// facelist::iterator iFace = result.begin();
|
||||
|
||||
// std::vector<TopoDS_Wire> fw;
|
||||
// int dbi = 0;
|
||||
// for (;iFace != result.end(); iFace++,dbi++) {
|
||||
// edgelist::iterator iEdge = (*iFace).begin();
|
||||
// std::vector<TopoDS_Edge> fe;
|
||||
// for (;iEdge != (*iFace).end(); iEdge++) {
|
||||
// fe.push_back(faceEdges.at((*iEdge).idx));
|
||||
// }
|
||||
// TopoDS_Wire w = makeCleanWire(fe);
|
||||
// fw.push_back(w);
|
||||
// }
|
||||
|
||||
TopoDS_Face projectedFace;
|
||||
|
||||
if (!fw.empty()) {
|
||||
std::vector<TopoDS_Wire> sortedWires = ew.sortStrip(fw, true);
|
||||
if (sortedWires.empty()) {
|
||||
return projectedFace;
|
||||
}
|
||||
//TODO: should have the same size checking logic as DVP?
|
||||
//remove the largest wire (OuterWire of graph) ??? but duplicates have been removed? only do this if a mosaic?
|
||||
//sortedWires.erase(sortedWires.begin());
|
||||
|
||||
BRepBuilderAPI_MakeFace mkFace(sortedWires.front(),true); //true => only want planes?
|
||||
std::vector<TopoDS_Wire>::iterator itWire = ++sortedWires.begin(); //starting with second face
|
||||
for (; itWire != sortedWires.end(); itWire++) {
|
||||
mkFace.Add(*itWire);
|
||||
}
|
||||
projectedFace = mkFace.Face();
|
||||
}
|
||||
|
||||
return projectedFace;
|
||||
}
|
||||
|
||||
//this should really be in BoundBox.h
|
||||
bool DrawViewSection::isReallyInBox (const Base::Vector3d v, const Base::BoundBox3d bb) const
|
||||
{
|
||||
if (v.x <= bb.MinX || v.x >= bb.MaxX)
|
||||
return false;
|
||||
if (v.y <= bb.MinY || v.y >= bb.MaxY)
|
||||
return false;
|
||||
if (v.z <= bb.MinZ || v.z >= bb.MaxZ)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Python Drawing feature ---------------------------------------------------------
|
||||
|
||||
namespace App {
|
||||
/// @cond DOXERR
|
||||
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewSectionPython, TechDraw::DrawViewSection)
|
||||
template<> const char* TechDraw::DrawViewSectionPython::getViewProviderName(void) const {
|
||||
return "TechDrawGui::ViewProviderDrawingView";
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
// explicit template instantiation
|
||||
template class TechDrawExport FeaturePythonT<TechDraw::DrawViewSection>;
|
||||
}
|
||||
|
|
|
@ -27,9 +27,24 @@
|
|||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepBndLib.hxx>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
|
||||
#include "DrawUtil.h"
|
||||
#include "EdgeWalker.h"
|
||||
|
||||
using namespace TechDraw;
|
||||
|
@ -47,22 +62,22 @@ void edgeVisitor::next_edge(Edge e)
|
|||
we.v1 = s;
|
||||
we.v2 = t;
|
||||
we.idx = get(edge_index,m_g,e);
|
||||
faceEdges.push_back(we);
|
||||
wireEdges.push_back(we);
|
||||
}
|
||||
|
||||
void edgeVisitor::begin_face()
|
||||
{
|
||||
faceEdges.clear();
|
||||
wireEdges.clear();
|
||||
}
|
||||
|
||||
void edgeVisitor::end_face()
|
||||
{
|
||||
graphFaces.push_back(faceEdges);
|
||||
graphWires.push_back(wireEdges);
|
||||
}
|
||||
|
||||
TechDraw::facelist edgeVisitor::getResult(void)
|
||||
TechDraw::ewWireList edgeVisitor::getResult(void)
|
||||
{
|
||||
return graphFaces;
|
||||
return graphWires;
|
||||
}
|
||||
|
||||
void edgeVisitor::setGraph(TechDraw::graph& g)
|
||||
|
@ -90,6 +105,15 @@ bool EdgeWalker::loadEdges(std::vector<TechDraw::WalkerEdge> edges)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EdgeWalker::loadEdges(std::vector<TopoDS_Edge> edges)
|
||||
{
|
||||
std::vector<TopoDS_Vertex> verts = makeUniqueVList(edges);
|
||||
setSize(verts.size());
|
||||
std::vector<WalkerEdge> we = makeWalkerEdges(edges, verts);
|
||||
saveInEdges = edges;
|
||||
|
||||
return loadEdges(we);
|
||||
}
|
||||
bool EdgeWalker::setSize(int size)
|
||||
{
|
||||
m_g.clear();
|
||||
|
@ -122,28 +146,153 @@ bool EdgeWalker::perform()
|
|||
return true;
|
||||
}
|
||||
|
||||
facelist EdgeWalker::getResult()
|
||||
ewWireList EdgeWalker::getResult()
|
||||
{
|
||||
TechDraw::facelist result = m_eV.getResult();
|
||||
return result;
|
||||
ewWireList result = m_eV.getResult();
|
||||
// result is a list of many wires each of which is a list of many WE
|
||||
return result;
|
||||
}
|
||||
|
||||
//static methods
|
||||
bool EdgeWalker::orderEdges(WalkerEdge i, WalkerEdge j)
|
||||
std::vector<TopoDS_Wire> EdgeWalker::getResultWires()
|
||||
{
|
||||
ewWireList result = m_eV.getResult();
|
||||
|
||||
std::vector<ewWire>::iterator iWire = result.wires.begin(); // a WE within [WE]
|
||||
std::vector<TopoDS_Wire> fw;
|
||||
for (;iWire != result.wires.end(); iWire++) {
|
||||
std::vector<WalkerEdge>::iterator iEdge = (*iWire).wedges.begin();
|
||||
std::vector<TopoDS_Edge> topoEdges;
|
||||
for (;iEdge != (*iWire).wedges.end(); iEdge++) {
|
||||
TopoDS_Edge e = saveInEdges.at((*iEdge).idx);
|
||||
topoEdges.push_back(e);
|
||||
}
|
||||
TopoDS_Wire w = makeCleanWire(topoEdges); //make 1 clean wire from its edges
|
||||
fw.push_back(w);
|
||||
}
|
||||
return fw;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Wire> EdgeWalker::getResultNoDups()
|
||||
{
|
||||
ewWireList result = m_eV.getResult();
|
||||
result = result.removeDuplicates();
|
||||
|
||||
std::vector<ewWire>::iterator iWire = result.wires.begin();
|
||||
std::vector<TopoDS_Wire> fw;
|
||||
for (;iWire != result.wires.end(); iWire++) {
|
||||
std::vector<WalkerEdge>::iterator iEdge = (*iWire).wedges.begin();
|
||||
std::vector<TopoDS_Edge> topoEdges;
|
||||
for (;iEdge != (*iWire).wedges.end(); iEdge++) {
|
||||
TopoDS_Edge e = saveInEdges.at((*iEdge).idx);
|
||||
topoEdges.push_back(e);
|
||||
}
|
||||
TopoDS_Wire w = makeCleanWire(topoEdges); //make 1 clean wire from its edges
|
||||
fw.push_back(w);
|
||||
}
|
||||
return fw;
|
||||
}
|
||||
|
||||
|
||||
//! make a clean wire with sorted, oriented, connected, etc edges
|
||||
TopoDS_Wire EdgeWalker::makeCleanWire(std::vector<TopoDS_Edge> edges, double tol)
|
||||
{
|
||||
TopoDS_Wire result;
|
||||
BRepBuilderAPI_MakeWire mkWire;
|
||||
ShapeFix_ShapeTolerance sTol;
|
||||
Handle(ShapeExtend_WireData) wireData = new ShapeExtend_WireData();
|
||||
|
||||
for (auto e:edges) {
|
||||
wireData->Add(e);
|
||||
}
|
||||
|
||||
Handle(ShapeFix_Wire) fixer = new ShapeFix_Wire;
|
||||
fixer->Load(wireData);
|
||||
fixer->Perform();
|
||||
fixer->FixReorder();
|
||||
fixer->SetMaxTolerance(tol);
|
||||
fixer->ClosedWireMode() = Standard_True;
|
||||
fixer->FixConnected(Precision::Confusion());
|
||||
fixer->FixClosed(Precision::Confusion());
|
||||
|
||||
for (int i = 1; i <= wireData->NbEdges(); i ++) {
|
||||
TopoDS_Edge edge = fixer->WireData()->Edge(i);
|
||||
sTol.SetTolerance(edge, tol, TopAbs_VERTEX);
|
||||
mkWire.Add(edge);
|
||||
}
|
||||
|
||||
result = mkWire.Wire();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Vertex> EdgeWalker:: makeUniqueVList(std::vector<TopoDS_Edge> edges)
|
||||
{
|
||||
std::vector<TopoDS_Vertex> uniqueVert;
|
||||
for(auto& e:edges) {
|
||||
TopoDS_Vertex v1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex v2 = TopExp::LastVertex(e);
|
||||
bool addv1 = true;
|
||||
bool addv2 = true;
|
||||
for (auto v:uniqueVert) {
|
||||
if (DrawUtil::isSamePoint(v,v1))
|
||||
addv1 = false;
|
||||
if (DrawUtil::isSamePoint(v,v2))
|
||||
addv2 = false;
|
||||
}
|
||||
if (addv1)
|
||||
uniqueVert.push_back(v1);
|
||||
if (addv2)
|
||||
uniqueVert.push_back(v2);
|
||||
}
|
||||
return uniqueVert;
|
||||
}
|
||||
|
||||
//!make WalkerEdges (unique Vertex index pairs) from edge list
|
||||
std::vector<WalkerEdge> EdgeWalker::makeWalkerEdges(std::vector<TopoDS_Edge> edges,
|
||||
std::vector<TopoDS_Vertex> verts)
|
||||
{
|
||||
std::vector<WalkerEdge> walkerEdges;
|
||||
for (auto e:edges) {
|
||||
TopoDS_Vertex ev1 = TopExp::FirstVertex(e);
|
||||
TopoDS_Vertex ev2 = TopExp::LastVertex(e);
|
||||
int v1dx = findUniqueVert(ev1, verts);
|
||||
int v2dx = findUniqueVert(ev2, verts);
|
||||
WalkerEdge we;
|
||||
we.v1 = v1dx;
|
||||
we.v2 = v2dx;
|
||||
walkerEdges.push_back(we);
|
||||
}
|
||||
return walkerEdges;
|
||||
}
|
||||
|
||||
int EdgeWalker::findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &uniqueVert)
|
||||
{
|
||||
int idx = 0;
|
||||
int result = 0;
|
||||
for(auto& v:uniqueVert) { //we're always going to find vx, right?
|
||||
if (DrawUtil::isSamePoint(v,vx)) {
|
||||
result = idx;
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
} //if idx >= uniqueVert.size() TARFU
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ bool WalkerEdge::weCompare(WalkerEdge i, WalkerEdge j)
|
||||
{
|
||||
return (i.idx < j.idx);
|
||||
}
|
||||
|
||||
bool EdgeWalker::isEqual(edgelist el1, edgelist el2)
|
||||
bool ewWire::isEqual(ewWire w2)
|
||||
{
|
||||
bool result = true;
|
||||
if (el1.size() != el2.size()) {
|
||||
if (wedges.size() != w2.wedges.size()) {
|
||||
result = false;
|
||||
} else {
|
||||
std::sort(el1.begin(),el1.end(),orderEdges);
|
||||
std::sort(el2.begin(),el2.end(),orderEdges);
|
||||
for (unsigned int i = 0; i < el1.size(); i ++) {
|
||||
if (el1.at(i).idx != el2.at(i).idx) {
|
||||
std::sort(wedges.begin(),wedges.end(),WalkerEdge::weCompare);
|
||||
std::sort(w2.wedges.begin(),w2.wedges.end(),WalkerEdge::weCompare);
|
||||
for (unsigned int i = 0; i < w2.wedges.size(); i ++) {
|
||||
if (wedges.at(i).idx != w2.wedges.at(i).idx) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
@ -152,23 +301,122 @@ bool EdgeWalker::isEqual(edgelist el1, edgelist el2)
|
|||
return result;
|
||||
}
|
||||
|
||||
//check faces that use the same set of edges, but maybe in a different order.
|
||||
facelist EdgeWalker::removeDuplicateFaces(facelist in)
|
||||
void ewWire::push_back(WalkerEdge w)
|
||||
{
|
||||
facelist result;
|
||||
result.push_back(*(in.begin())); //save the first edgelist
|
||||
facelist::iterator iFace = (in.begin()) + 1; //starting with second
|
||||
for (; iFace != in.end(); iFace++) {
|
||||
wedges.push_back(w);
|
||||
}
|
||||
|
||||
//check wirelist for wires that use the same set of edges, but maybe in a different order.
|
||||
ewWireList ewWireList::removeDuplicates()
|
||||
{
|
||||
ewWireList result;
|
||||
result.push_back(*(wires.begin())); //save the first ewWire
|
||||
std::vector<ewWire>::iterator iWire = (wires.begin()) + 1; //starting with second
|
||||
for (; iWire != wires.end(); iWire++) {
|
||||
bool addToResult = true;
|
||||
for (auto& e:result) {
|
||||
if (isEqual((*iFace),e)) { //already in result?
|
||||
for (auto& w:result.wires) {
|
||||
if ((*iWire).isEqual(w)) { //already in result?
|
||||
addToResult = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (addToResult) {
|
||||
result.push_back((*iFace));
|
||||
result.push_back((*iWire));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ewWireList::push_back(ewWire w)
|
||||
{
|
||||
wires.push_back(w);
|
||||
}
|
||||
|
||||
|
||||
std::vector<TopoDS_Wire> EdgeWalker::sortStrip(std::vector<TopoDS_Wire> fw, bool includeBiggest)
|
||||
{
|
||||
std::vector<TopoDS_Wire> sortedWires = sortWiresBySize(fw,false); //biggest 1st
|
||||
if (!sortedWires.size()) {
|
||||
Base::Console().Log("INFO - DVP::extractFaces - no sorted Wires!\n");
|
||||
return sortedWires; // might happen in the middle of changes?
|
||||
}
|
||||
|
||||
if (includeBiggest) {
|
||||
return sortedWires; // all the wires
|
||||
}
|
||||
|
||||
//remove the largest wire (OuterWire of graph) wf: still not convinced we should do this in all cases.
|
||||
Bnd_Box bigBox;
|
||||
if (sortedWires.size() && !sortedWires.front().IsNull()) {
|
||||
BRepBndLib::Add(sortedWires.front(), bigBox);
|
||||
bigBox.SetGap(0.0);
|
||||
}
|
||||
std::vector<std::size_t> toBeChecked;
|
||||
std::vector<TopoDS_Wire>::iterator it = sortedWires.begin() + 1;
|
||||
for (; it != sortedWires.end(); it++) {
|
||||
if (!(*it).IsNull()) {
|
||||
Bnd_Box littleBox;
|
||||
BRepBndLib::Add((*it), littleBox);
|
||||
littleBox.SetGap(0.0);
|
||||
if (bigBox.SquareExtent() > littleBox.SquareExtent()) {
|
||||
break;
|
||||
} else {
|
||||
auto position = std::distance( sortedWires.begin(), it ); //get an index from iterator
|
||||
toBeChecked.push_back(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
//unfortuneately, faces can have same bbox, but not be same size. need to weed out biggest
|
||||
if (toBeChecked.size() == 0) {
|
||||
//nobody had as big a bbox as first element of sortedWires
|
||||
sortedWires.erase(sortedWires.begin());
|
||||
} else if (toBeChecked.size() > 0) {
|
||||
BRepBuilderAPI_MakeFace mkFace(sortedWires.front());
|
||||
const TopoDS_Face& face = mkFace.Face();
|
||||
GProp_GProps props;
|
||||
BRepGProp::SurfaceProperties(face, props);
|
||||
double bigArea = props.Mass();
|
||||
unsigned int bigIndex = 0;
|
||||
for (unsigned int idx = 1; idx < toBeChecked.size(); idx++) {
|
||||
BRepBuilderAPI_MakeFace mkFace2(sortedWires.at(idx));
|
||||
const TopoDS_Face& face2 = mkFace2.Face();
|
||||
BRepGProp::SurfaceProperties(face2, props);
|
||||
double area = props.Mass();
|
||||
if (area > bigArea) {
|
||||
bigArea = area;
|
||||
bigIndex = idx;
|
||||
}
|
||||
}
|
||||
sortedWires.erase(sortedWires.begin() + bigIndex);
|
||||
}
|
||||
return sortedWires;
|
||||
}
|
||||
|
||||
//sort wires in order of bbox diagonal.
|
||||
std::vector<TopoDS_Wire> EdgeWalker::sortWiresBySize(std::vector<TopoDS_Wire>& w, bool ascend)
|
||||
{
|
||||
std::vector<TopoDS_Wire> wires = w;
|
||||
std::sort(wires.begin(), wires.end(), EdgeWalker::wireCompare);
|
||||
if (ascend) {
|
||||
std::reverse(wires.begin(),wires.end());
|
||||
}
|
||||
return wires;
|
||||
}
|
||||
|
||||
//! return true if w1 bbox is bigger than w2 bbox
|
||||
//NOTE: this won't necessarily sort the OuterWire correctly (ex smaller wire, same bbox)
|
||||
/*static*/bool EdgeWalker::wireCompare(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();
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@
|
|||
#include <boost/graph/planar_face_traversal.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
namespace TechDraw {
|
||||
using namespace boost;
|
||||
|
||||
|
@ -51,14 +55,35 @@ typedef adjacency_list
|
|||
>
|
||||
graph;
|
||||
|
||||
struct WalkerEdge {
|
||||
class WalkerEdge
|
||||
{
|
||||
public:
|
||||
static bool weCompare(WalkerEdge i, WalkerEdge j);
|
||||
|
||||
std::size_t v1;
|
||||
std::size_t v2;
|
||||
int idx;
|
||||
};
|
||||
|
||||
typedef std::vector<WalkerEdge> edgelist;
|
||||
typedef std::vector<edgelist> facelist ;
|
||||
class ewWire
|
||||
{
|
||||
public:
|
||||
bool isEqual(ewWire w);
|
||||
|
||||
std::vector<WalkerEdge> wedges; //[WE] representing 1 wire
|
||||
void push_back(WalkerEdge w);
|
||||
void clear() {wedges.clear();};
|
||||
};
|
||||
|
||||
class ewWireList
|
||||
{
|
||||
public:
|
||||
ewWireList removeDuplicates();
|
||||
|
||||
std::vector<ewWire> wires;
|
||||
void push_back(ewWire e);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class edgeVisitor : public planar_face_traversal_visitor
|
||||
|
@ -68,12 +93,12 @@ public:
|
|||
void next_edge(Edge e);
|
||||
void begin_face();
|
||||
void end_face();
|
||||
facelist getResult(void);
|
||||
ewWireList getResult(void); //a list of many wires
|
||||
void setGraph(graph& g);
|
||||
|
||||
private:
|
||||
TechDraw::edgelist faceEdges;
|
||||
TechDraw::facelist graphFaces;
|
||||
ewWire wireEdges;
|
||||
ewWireList graphWires;
|
||||
TechDraw::graph m_g;
|
||||
};
|
||||
|
||||
|
@ -84,18 +109,31 @@ public:
|
|||
virtual ~EdgeWalker();
|
||||
|
||||
bool loadEdges(std::vector<TechDraw::WalkerEdge> edges);
|
||||
bool loadEdges(std::vector<TopoDS_Edge> edges);
|
||||
bool setSize(int size);
|
||||
bool perform();
|
||||
facelist getResult();
|
||||
static bool orderEdges(WalkerEdge i, WalkerEdge j);
|
||||
static bool isEqual(edgelist el1, edgelist el2);
|
||||
static facelist removeDuplicateFaces(facelist in);
|
||||
ewWireList getResult();
|
||||
std::vector<TopoDS_Wire> getResultWires();
|
||||
std::vector<TopoDS_Wire> getResultNoDups();
|
||||
|
||||
std::vector<TopoDS_Vertex> makeUniqueVList(std::vector<TopoDS_Edge> edges);
|
||||
std::vector<WalkerEdge> makeWalkerEdges(std::vector<TopoDS_Edge> edges,
|
||||
std::vector<TopoDS_Vertex> verts);
|
||||
int findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &uniqueVert);
|
||||
std::vector<TopoDS_Wire> sortStrip(std::vector<TopoDS_Wire> fw, bool includeBiggest);
|
||||
std::vector<TopoDS_Wire> sortWiresBySize(std::vector<TopoDS_Wire>& w, bool reverse = false);
|
||||
TopoDS_Wire makeCleanWire(std::vector<TopoDS_Edge> edges, double tol = 0.10);
|
||||
|
||||
|
||||
protected:
|
||||
static bool wireCompare(const TopoDS_Wire& w1, const TopoDS_Wire& w2);
|
||||
std::vector<TopoDS_Edge> saveInEdges;
|
||||
|
||||
private:
|
||||
edgeVisitor m_eV;
|
||||
TechDraw::graph m_g;
|
||||
};
|
||||
|
||||
} //end namespace
|
||||
} //end namespace TechDraw
|
||||
|
||||
#endif //TECHDRAW_EDGEWALKER_H
|
||||
|
|
Loading…
Reference in New Issue
Block a user