Path.Area added coplanar check parameter
This commit is contained in:
parent
36423f24de
commit
1517418ba0
|
@ -111,22 +111,47 @@ Area::~Area() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Area::setPlane(const TopoDS_Shape &shape) {
|
void Area::setPlane(const TopoDS_Shape &shape) {
|
||||||
|
if(shape.IsNull()) {
|
||||||
|
myWorkPlane.Nullify();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
BRepLib_FindSurface planeFinder(shape,-1,Standard_True);
|
||||||
|
if (!planeFinder.Found())
|
||||||
|
throw Base::ValueError("shape is not coplanar");
|
||||||
myWorkPlane = shape;
|
myWorkPlane = shape;
|
||||||
|
myTrsf.SetTransformation(GeomAdaptor_Surface(
|
||||||
|
planeFinder.Surface()).Plane().Position());
|
||||||
|
clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Area::add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf,
|
bool Area::isCoplanar(const TopoDS_Shape &s1, const TopoDS_Shape &s2) {
|
||||||
double deflection, CArea *areaOpen, bool to_edges, bool reorder)
|
TopoDS_Builder builder;
|
||||||
|
TopoDS_Compound comp;
|
||||||
|
builder.MakeCompound(comp);
|
||||||
|
builder.Add(comp,s1);
|
||||||
|
builder.Add(comp,s2);
|
||||||
|
BRepLib_FindSurface planeFinder(comp,-1,Standard_True);
|
||||||
|
return planeFinder.Found();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Area::add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf,
|
||||||
|
double deflection, const TopoDS_Shape *plane, bool force_coplanar,
|
||||||
|
CArea *areaOpen, bool to_edges, bool reorder)
|
||||||
{
|
{
|
||||||
bool haveShape = false;
|
bool haveShape = false;
|
||||||
|
int skipped = 0;
|
||||||
for (TopExp_Explorer it(shape, TopAbs_FACE); it.More(); it.Next()) {
|
for (TopExp_Explorer it(shape, TopAbs_FACE); it.More(); it.Next()) {
|
||||||
haveShape = true;
|
haveShape = true;
|
||||||
const TopoDS_Face &face = TopoDS::Face(it.Current());
|
const TopoDS_Face &face = TopoDS::Face(it.Current());
|
||||||
|
if(plane && !isCoplanar(face,*plane)) {
|
||||||
|
++skipped;
|
||||||
|
if(force_coplanar) continue;
|
||||||
|
}
|
||||||
for (TopExp_Explorer it(face, TopAbs_WIRE); it.More(); it.Next())
|
for (TopExp_Explorer it(face, TopAbs_WIRE); it.More(); it.Next())
|
||||||
add(area,TopoDS::Wire(it.Current()),trsf,deflection);
|
add(area,TopoDS::Wire(it.Current()),trsf,deflection);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(haveShape) return;
|
if(haveShape) return skipped;
|
||||||
|
|
||||||
CArea _area;
|
CArea _area;
|
||||||
CArea _areaOpen;
|
CArea _areaOpen;
|
||||||
|
@ -134,6 +159,10 @@ void Area::add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf,
|
||||||
for (TopExp_Explorer it(shape, TopAbs_WIRE); it.More(); it.Next()) {
|
for (TopExp_Explorer it(shape, TopAbs_WIRE); it.More(); it.Next()) {
|
||||||
haveShape = true;
|
haveShape = true;
|
||||||
const TopoDS_Wire &wire = TopoDS::Wire(it.Current());
|
const TopoDS_Wire &wire = TopoDS::Wire(it.Current());
|
||||||
|
if(plane && !isCoplanar(wire,*plane)) {
|
||||||
|
++skipped;
|
||||||
|
if(force_coplanar) continue;
|
||||||
|
}
|
||||||
if(BRep_Tool::IsClosed(wire))
|
if(BRep_Tool::IsClosed(wire))
|
||||||
add(_area,wire,trsf,deflection);
|
add(_area,wire,trsf,deflection);
|
||||||
else if(to_edges) {
|
else if(to_edges) {
|
||||||
|
@ -146,6 +175,10 @@ void Area::add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf,
|
||||||
|
|
||||||
if(!haveShape) {
|
if(!haveShape) {
|
||||||
for (TopExp_Explorer it(shape, TopAbs_EDGE); it.More(); it.Next()) {
|
for (TopExp_Explorer it(shape, TopAbs_EDGE); it.More(); it.Next()) {
|
||||||
|
if(plane && !isCoplanar(it.Current(),*plane)) {
|
||||||
|
++skipped;
|
||||||
|
if(force_coplanar) continue;
|
||||||
|
}
|
||||||
add(_areaOpen,BRepBuilderAPI_MakeWire(
|
add(_areaOpen,BRepBuilderAPI_MakeWire(
|
||||||
TopoDS::Edge(it.Current())).Wire(),trsf,deflection);
|
TopoDS::Edge(it.Current())).Wire(),trsf,deflection);
|
||||||
}
|
}
|
||||||
|
@ -158,6 +191,7 @@ void Area::add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf,
|
||||||
areaOpen->m_curves.splice(areaOpen->m_curves.end(),_areaOpen.m_curves);
|
areaOpen->m_curves.splice(areaOpen->m_curves.end(),_areaOpen.m_curves);
|
||||||
else
|
else
|
||||||
area.m_curves.splice(area.m_curves.end(),_areaOpen.m_curves);
|
area.m_curves.splice(area.m_curves.end(),_areaOpen.m_curves);
|
||||||
|
return skipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Area::add(CArea &area, const TopoDS_Wire& wire,
|
void Area::add(CArea &area, const TopoDS_Wire& wire,
|
||||||
|
@ -227,16 +261,16 @@ void Area::clean(bool deleteShapes) {
|
||||||
myArea = NULL;
|
myArea = NULL;
|
||||||
delete myAreaOpen;
|
delete myAreaOpen;
|
||||||
myAreaOpen = NULL;
|
myAreaOpen = NULL;
|
||||||
if(deleteShapes)
|
if(deleteShapes){
|
||||||
|
myShapePlane.Nullify();
|
||||||
myShapes.clear();
|
myShapes.clear();
|
||||||
|
myHaveFace = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Area::add(const TopoDS_Shape &shape,short op) {
|
void Area::add(const TopoDS_Shape &shape,short op) {
|
||||||
#define AREA_SRC_OP(_v) op
|
#define AREA_SRC_OP(_v) op
|
||||||
PARAM_ENUM_CONVERT(AREA_SRC_OP,,PARAM_ENUM_EXCEPT,AREA_PARAMS_OPCODE);
|
PARAM_ENUM_CONVERT(AREA_SRC_OP,,PARAM_ENUM_EXCEPT,AREA_PARAMS_OPCODE);
|
||||||
TopExp_Explorer it(shape, TopAbs_SHELL);
|
|
||||||
if(it.More())
|
|
||||||
throw Base::ValueError("not a 2D shape");
|
|
||||||
clean();
|
clean();
|
||||||
if(myShapes.empty())
|
if(myShapes.empty())
|
||||||
Operation = ClipperLib::ctUnion;
|
Operation = ClipperLib::ctUnion;
|
||||||
|
@ -258,8 +292,14 @@ void Area::addToBuild(CArea &area, const TopoDS_Shape &shape) {
|
||||||
TopExp_Explorer it(shape, TopAbs_FACE);
|
TopExp_Explorer it(shape, TopAbs_FACE);
|
||||||
myHaveFace = it.More();
|
myHaveFace = it.More();
|
||||||
}
|
}
|
||||||
|
const TopoDS_Shape *plane;
|
||||||
|
if(myParams.Coplanar == CoplanarNone)
|
||||||
|
plane = NULL;
|
||||||
|
else
|
||||||
|
plane = myWorkPlane.IsNull()?&myShapePlane:&myWorkPlane;
|
||||||
CArea areaOpen;
|
CArea areaOpen;
|
||||||
add(area,shape,&myTrsf,myParams.Deflection,&areaOpen,
|
mySkippedShapes += add(area,shape,&myTrsf,myParams.Deflection,plane,
|
||||||
|
myParams.Coplanar==CoplanarForce,&areaOpen,
|
||||||
myParams.OpenMode==OpenModeEdges,myParams.Reorder);
|
myParams.OpenMode==OpenModeEdges,myParams.Reorder);
|
||||||
if(areaOpen.m_curves.size()) {
|
if(areaOpen.m_curves.size()) {
|
||||||
if(&area == myArea || myParams.OpenMode == OpenModeNone)
|
if(&area == myArea || myParams.OpenMode == OpenModeNone)
|
||||||
|
@ -278,48 +318,75 @@ void Area::build() {
|
||||||
#define AREA_SRC(_v) myParams._v
|
#define AREA_SRC(_v) myParams._v
|
||||||
PARAM_ENUM_CONVERT(AREA_SRC,,PARAM_ENUM_EXCEPT,AREA_PARAMS_CLIPPER_FILL);
|
PARAM_ENUM_CONVERT(AREA_SRC,,PARAM_ENUM_EXCEPT,AREA_PARAMS_CLIPPER_FILL);
|
||||||
|
|
||||||
TopoDS_Builder builder;
|
if(myWorkPlane.IsNull()) {
|
||||||
TopoDS_Compound comp;
|
myShapePlane.Nullify();
|
||||||
builder.MakeCompound(comp);
|
for(const Shape &s : myShapes) {
|
||||||
if(!myWorkPlane.IsNull())
|
bool haveFace = false;
|
||||||
builder.Add(comp,myWorkPlane);
|
for(TopExp_Explorer it(s.shape, TopAbs_FACE); it.More(); it.Next()) {
|
||||||
else {
|
haveFace = true;
|
||||||
for(const Shape &s : myShapes)
|
BRepLib_FindSurface planeFinder(it.Current(),-1,Standard_True);
|
||||||
builder.Add(comp, s.shape);
|
if (!planeFinder.Found())
|
||||||
|
continue;
|
||||||
|
myShapePlane = it.Current();
|
||||||
|
myTrsf.SetTransformation(GeomAdaptor_Surface(
|
||||||
|
planeFinder.Surface()).Plane().Position());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!myShapePlane.IsNull()) break;
|
||||||
|
if(haveFace) continue;
|
||||||
|
for(TopExp_Explorer it(s.shape, TopAbs_WIRE); it.More(); it.Next()) {
|
||||||
|
BRepLib_FindSurface planeFinder(it.Current(),-1,Standard_True);
|
||||||
|
if (!planeFinder.Found())
|
||||||
|
continue;
|
||||||
|
myShapePlane = it.Current();
|
||||||
|
myTrsf.SetTransformation(GeomAdaptor_Surface(
|
||||||
|
planeFinder.Surface()).Plane().Position());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!myShapePlane.IsNull()) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(myShapePlane.IsNull())
|
||||||
|
throw Base::ValueError("shapes are not planar");
|
||||||
}
|
}
|
||||||
BRepLib_FindSurface planeFinder(comp,-1,Standard_True);
|
|
||||||
if (!planeFinder.Found())
|
|
||||||
throw Base::ValueError("shapes are not coplanar");
|
|
||||||
|
|
||||||
myTrsf.SetTransformation(GeomAdaptor_Surface(
|
try {
|
||||||
planeFinder.Surface()).Plane().Position());
|
myArea = new CArea();
|
||||||
|
myAreaOpen = new CArea();
|
||||||
|
|
||||||
myArea = new CArea();
|
CAreaConfig conf(myParams);
|
||||||
myAreaOpen = new CArea();
|
CArea areaClip;
|
||||||
|
|
||||||
CAreaConfig conf(myParams);
|
mySkippedShapes = 0;
|
||||||
CArea areaClip;
|
short op = ClipperLib::ctUnion;
|
||||||
|
bool pending = false;
|
||||||
|
for(const Shape &s : myShapes) {
|
||||||
|
if(op!=s.op) {
|
||||||
|
if(myParams.OpenMode!=OpenModeNone)
|
||||||
|
myArea->m_curves.splice(myArea->m_curves.end(),myAreaOpen->m_curves);
|
||||||
|
pending = false;
|
||||||
|
myArea->Clip((ClipperLib::ClipType)op,&areaClip,SubjectFill,ClipFill);
|
||||||
|
areaClip.m_curves.clear();
|
||||||
|
op=s.op;
|
||||||
|
}
|
||||||
|
addToBuild(op==ClipperLib::ctUnion?*myArea:areaClip,s.shape);
|
||||||
|
pending = true;
|
||||||
|
}
|
||||||
|
if(mySkippedShapes)
|
||||||
|
Base::Console().Warning("%s %d non coplanar shapes\n",
|
||||||
|
myParams.Coplanar==CoplanarForce?"Skipped":"Found",mySkippedShapes);
|
||||||
|
|
||||||
short op = ClipperLib::ctUnion;
|
if(pending){
|
||||||
bool pending = false;
|
|
||||||
for(const Shape &s : myShapes) {
|
|
||||||
if(op!=s.op) {
|
|
||||||
if(myParams.OpenMode!=OpenModeNone)
|
if(myParams.OpenMode!=OpenModeNone)
|
||||||
myArea->m_curves.splice(myArea->m_curves.end(),myAreaOpen->m_curves);
|
myArea->m_curves.splice(myArea->m_curves.end(),myAreaOpen->m_curves);
|
||||||
pending = false;
|
|
||||||
myArea->Clip((ClipperLib::ClipType)op,&areaClip,SubjectFill,ClipFill);
|
myArea->Clip((ClipperLib::ClipType)op,&areaClip,SubjectFill,ClipFill);
|
||||||
areaClip.m_curves.clear();
|
|
||||||
op=s.op;
|
|
||||||
}
|
}
|
||||||
addToBuild(op==ClipperLib::ctUnion?*myArea:areaClip,s.shape);
|
myArea->m_curves.splice(myArea->m_curves.end(),myAreaOpen->m_curves);
|
||||||
pending = true;
|
|
||||||
|
}catch(...) {
|
||||||
|
clean();
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
if(pending){
|
|
||||||
if(myParams.OpenMode!=OpenModeNone)
|
|
||||||
myArea->m_curves.splice(myArea->m_curves.end(),myAreaOpen->m_curves);
|
|
||||||
myArea->Clip((ClipperLib::ClipType)op,&areaClip,SubjectFill,ClipFill);
|
|
||||||
}
|
|
||||||
myArea->m_curves.splice(myArea->m_curves.end(),myAreaOpen->m_curves);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TopoDS_Shape Area::toShape(CArea &area, short fill) {
|
TopoDS_Shape Area::toShape(CArea &area, short fill) {
|
||||||
|
|
|
@ -109,9 +109,11 @@ protected:
|
||||||
CArea *myAreaOpen;
|
CArea *myAreaOpen;
|
||||||
gp_Trsf myTrsf;
|
gp_Trsf myTrsf;
|
||||||
AreaParams myParams;
|
AreaParams myParams;
|
||||||
|
TopoDS_Shape myShapePlane;
|
||||||
TopoDS_Shape myWorkPlane;
|
TopoDS_Shape myWorkPlane;
|
||||||
TopoDS_Shape myShape;
|
TopoDS_Shape myShape;
|
||||||
bool myHaveFace;
|
bool myHaveFace;
|
||||||
|
int mySkippedShapes;
|
||||||
|
|
||||||
/** Called internally to combine children shapes for further processing */
|
/** Called internally to combine children shapes for further processing */
|
||||||
void build();
|
void build();
|
||||||
|
@ -205,7 +207,7 @@ public:
|
||||||
* \arg \c deflection: for defecting non circular curves
|
* \arg \c deflection: for defecting non circular curves
|
||||||
* */
|
* */
|
||||||
static void add(CArea &area, const TopoDS_Wire &wire,
|
static void add(CArea &area, const TopoDS_Wire &wire,
|
||||||
const gp_Trsf *trsf=NULL,double deflection=0.01);
|
const gp_Trsf *trsf=NULL, double deflection=0.01);
|
||||||
|
|
||||||
/** Add a OCC generic shape to CArea
|
/** Add a OCC generic shape to CArea
|
||||||
*
|
*
|
||||||
|
@ -214,13 +216,20 @@ public:
|
||||||
* \arg \c trsf: optional transform matrix to transform the wire shape into
|
* \arg \c trsf: optional transform matrix to transform the wire shape into
|
||||||
* XY0 plane.
|
* XY0 plane.
|
||||||
* \arg \c deflection: for defecting non circular curves
|
* \arg \c deflection: for defecting non circular curves
|
||||||
|
* \arg \c plane: a shape for testing coplanar
|
||||||
|
* \arg \c force_coplaner: if true, discard non-coplanar shapes.
|
||||||
* \arg \c areaOpen: for collecting open curves. If not supplied, open
|
* \arg \c areaOpen: for collecting open curves. If not supplied, open
|
||||||
* curves are added to \c area
|
* curves are added to \c area
|
||||||
* \arg \c to_edges: separate open wires to individual edges
|
* \arg \c to_edges: separate open wires to individual edges
|
||||||
* \arg \c reorder: reorder closed wires for wire only shape
|
* \arg \c reorder: reorder closed wires for wire only shape
|
||||||
|
*
|
||||||
|
* \return Returns the number of non coplaner. Planar testing only happens
|
||||||
|
* if \c plane is supplied
|
||||||
* */
|
* */
|
||||||
static void add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf=NULL,
|
static int add(CArea &area, const TopoDS_Shape &shape, const gp_Trsf *trsf=NULL,
|
||||||
double deflection=0.01,CArea *areaOpen=NULL, bool to_edges=false, bool reorder=true);
|
double deflection=0.01,const TopoDS_Shape *plane = NULL,
|
||||||
|
bool force_coplanar=true, CArea *areaOpen=NULL, bool to_edges=false,
|
||||||
|
bool reorder=true);
|
||||||
|
|
||||||
/** Convert curves in CArea into an OCC shape
|
/** Convert curves in CArea into an OCC shape
|
||||||
*
|
*
|
||||||
|
@ -231,6 +240,8 @@ public:
|
||||||
* */
|
* */
|
||||||
static TopoDS_Shape toShape(const CArea &area, bool fill,
|
static TopoDS_Shape toShape(const CArea &area, bool fill,
|
||||||
const gp_Trsf *trsf=NULL);
|
const gp_Trsf *trsf=NULL);
|
||||||
|
|
||||||
|
static bool isCoplanar(const TopoDS_Shape &s1, const TopoDS_Shape &s2);
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace Path
|
} //namespace Path
|
||||||
|
|
|
@ -48,6 +48,9 @@
|
||||||
#define AREA_PARAMS_BASE \
|
#define AREA_PARAMS_BASE \
|
||||||
((enum,fill,Fill,2,"Fill the output wires to make a face. \n"\
|
((enum,fill,Fill,2,"Fill the output wires to make a face. \n"\
|
||||||
"Auto means make a face if any of the children has a face.",(None)(Face)(Auto)))\
|
"Auto means make a face if any of the children has a face.",(None)(Face)(Auto)))\
|
||||||
|
((enum,coplanar,Coplanar,2,"Specifies the way to check coplanar.\n"\
|
||||||
|
"'Force' will discard non coplaner shapes, but 'Check' only gives warning.",\
|
||||||
|
(None)(Check)(Force)))\
|
||||||
((bool,reorder,Reorder,false,"Re-orient closed wires in wire only shapes so that inner wires become holes."))\
|
((bool,reorder,Reorder,false,"Re-orient closed wires in wire only shapes so that inner wires become holes."))\
|
||||||
((enum,open_mode,OpenMode,0,"Specify how to handle open wires.\n"\
|
((enum,open_mode,OpenMode,0,"Specify how to handle open wires.\n"\
|
||||||
"'None' means combin without openeration.\n"\
|
"'None' means combin without openeration.\n"\
|
||||||
|
|
Loading…
Reference in New Issue
Block a user