Part: TopoShapePy: add generalFuse method

This commit is contained in:
DeepSOIC 2016-07-04 14:57:50 +03:00
parent c8ebc7f9c2
commit 885fecb1ea
2 changed files with 130 additions and 5 deletions

View File

@ -180,6 +180,33 @@ Beginning from OCCT 6.8.1 a tolerance value can be specified</UserDocu>
<UserDocu>Difference of this and a given topo shape.</UserDocu>
</Documentation>
</Methode>
<Methode Name="generalFuse" Const="true">
<Documentation>
<UserDocu>generalFuse(list_of_other_shapes, fuzzy_value = 0.0): Run general fuse algorithm (GFA) between this and given shapes.
list_of_other_shapes: shapes to run the algorithm against (the list is
effectively prepended by 'self').
fuzzy_value: extra tolerance to apply when searching for interferences, in
addition to tolerances of the input shapes.
Returns a tuple of 2: (result, map).
result is a compound containing all the pieces generated by the algorithm
(e.g., for two spheres, the pieces are three touching solids). Pieces that
touch share elements.
map is a list of lists of shapes, providing the info on which children of
result came from which argument. The length of list is equal to length of
list_of_other_shapes + 1. First element is a list of pieces that came from
shape of this, and the rest are those that come from corresponding shapes in
list_of_other_shapes.
hint: use isSame method to test shape equality
OCC 6.9.0 or later is required.
</UserDocu>
</Documentation>
</Methode>
<Methode Name="sewShape">
<Documentation>
<UserDocu>Sew the shape if there is a gap.</UserDocu>
@ -190,11 +217,11 @@ Beginning from OCCT 6.8.1 a tolerance value can be specified</UserDocu>
<UserDocu>
childShapes([cumOri=True, cumLoc=True]) -> list
Return a list of sub-shapes that are direct children of this shape.
* If cumOri is true, the function composes all
sub-shapes with the orientation of this shape.
* If cumLoc is true, the function multiplies all
sub-shapes by the location of this shape, i.e. it applies to
each sub-shape the transformation that is associated with this shape.
* If cumOri is true, the function composes all
sub-shapes with the orientation of this shape.
* If cumLoc is true, the function multiplies all
sub-shapes by the location of this shape, i.e. it applies to
each sub-shape the transformation that is associated with this shape.
</UserDocu>
</Documentation>
</Methode>

View File

@ -49,6 +49,8 @@
# include <TopoDS.hxx>
# include <TopoDS_Iterator.hxx>
# include <TopTools_IndexedMapOfShape.hxx>
# include <TopTools_ListOfShape.hxx>
# include <TopTools_ListIteratorOfListOfShape.hxx>
# include <TopLoc_Location.hxx>
# include <TopExp.hxx>
# include <Precision.hxx>
@ -153,6 +155,54 @@ int TopoShapePy::PyInit(PyObject* args, PyObject*)
return 0;
}
//common code.. maybe put somewhere else?
Py::Object shape2pyshape(const TopoDS_Shape &shape)
{
PyObject* ret = 0;
if (!shape.IsNull()) {
TopAbs_ShapeEnum type = shape.ShapeType();
switch (type)
{
case TopAbs_COMPOUND:
ret = new TopoShapeCompoundPy(new TopoShape(shape));
break;
case TopAbs_COMPSOLID:
ret = new TopoShapeCompSolidPy(new TopoShape(shape));
break;
case TopAbs_SOLID:
ret = new TopoShapeSolidPy(new TopoShape(shape));
break;
case TopAbs_SHELL:
ret = new TopoShapeShellPy(new TopoShape(shape));
break;
case TopAbs_FACE:
ret = new TopoShapeFacePy(new TopoShape(shape));
break;
case TopAbs_WIRE:
ret = new TopoShapeWirePy(new TopoShape(shape));
break;
case TopAbs_EDGE:
ret = new TopoShapeEdgePy(new TopoShape(shape));
break;
case TopAbs_VERTEX:
ret = new TopoShapeVertexPy(new TopoShape(shape));
break;
case TopAbs_SHAPE:
ret = new TopoShapePy(new TopoShape(shape));
break;
default:
//shouldn't happen
ret = new TopoShapePy(new TopoShape(shape));
break;
}
} else {
ret = new TopoShapePy(new TopoShape(shape));
}
assert(ret);
return Py::asObject(ret);
}
PyObject* TopoShapePy::copy(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))
@ -907,6 +957,54 @@ PyObject* TopoShapePy::cut(PyObject *args)
}
}
PyObject* TopoShapePy::generalFuse(PyObject *args)
{
double tolerance = 0.0;
PyObject *pcObj;
if (!PyArg_ParseTuple(args, "O|d", &pcObj, &tolerance))
return NULL;
std::vector<TopoDS_Shape> shapeVec;
Py::Sequence shapeSeq(pcObj);
for (Py::Sequence::iterator it = shapeSeq.begin(); it != shapeSeq.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
shapeVec.push_back(static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->_Shape);
}
else {
PyErr_SetString(PyExc_TypeError, "non-shape object in sequence");
return 0;
}
}
try {
std::vector<TopTools_ListOfShape> map;
TopoDS_Shape gfaResultShape = this->getTopoShapePtr()->generalFuse(shapeVec,tolerance,&map);
Py::Object shapePy = shape2pyshape(gfaResultShape);
Py::List mapPy;
for(TopTools_ListOfShape &shapes: map){
Py::List shapesPy;
for(TopTools_ListIteratorOfListOfShape it(shapes); it.More(); it.Next()){
shapesPy.append(shape2pyshape(it.Value()));
}
mapPy.append(shapesPy);
}
Py::Tuple ret(2);
ret[0] = shapePy;
ret[1] = mapPy;
return Py::new_reference_to(ret);
}
catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
return NULL;
}
catch (const std::exception& e) {
PyErr_SetString(PartExceptionOCCError, e.what());
return NULL;
}
}
PyObject* TopoShapePy::sewShape(PyObject *args)
{
if (!PyArg_ParseTuple(args, ""))