Py: fix memory leaks by incorrect use of PyList_Append
This commit is contained in:
@@ -793,21 +793,20 @@ private:
|
||||
Py::Object getFacets(const Py::Tuple& args)
|
||||
{
|
||||
PyObject *shape;
|
||||
PyObject *list = PyList_New(0);
|
||||
Py::List list;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "O", &shape))
|
||||
throw Py::Exception();
|
||||
auto theShape = static_cast<Part::TopoShapePy*>(shape)->getTopoShapePtr()->getShape();
|
||||
for(TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next())
|
||||
{
|
||||
for (TopExp_Explorer ex(theShape, TopAbs_FACE); ex.More(); ex.Next()) {
|
||||
TopoDS_Face currentFace = TopoDS::Face(ex.Current());
|
||||
TopLoc_Location loc;
|
||||
Handle(Poly_Triangulation) facets = BRep_Tool::Triangulation(currentFace, loc);
|
||||
const TopAbs_Orientation anOrientation = currentFace.Orientation();
|
||||
bool flip = (anOrientation == TopAbs_REVERSED);
|
||||
if(!facets.IsNull()){
|
||||
if (!facets.IsNull()) {
|
||||
const TColgp_Array1OfPnt& nodes = facets->Nodes();
|
||||
const Poly_Array1OfTriangle& triangles = facets->Triangles();
|
||||
for(int i = 1; i <= triangles.Length(); i++){
|
||||
for (int i = 1; i <= triangles.Length(); i++) {
|
||||
Standard_Integer n1,n2,n3;
|
||||
triangles(i).Get(n1, n2, n3);
|
||||
gp_Pnt p1 = nodes(n1);
|
||||
@@ -821,19 +820,17 @@ private:
|
||||
PyObject *t1 = PyTuple_Pack(3, PyFloat_FromDouble(p1.X()), PyFloat_FromDouble(p1.Y()), PyFloat_FromDouble(p1.Z()));
|
||||
PyObject *t2 = PyTuple_Pack(3, PyFloat_FromDouble(p2.X()), PyFloat_FromDouble(p2.Y()), PyFloat_FromDouble(p2.Z()));
|
||||
PyObject *t3 = PyTuple_Pack(3, PyFloat_FromDouble(p3.X()), PyFloat_FromDouble(p3.Y()), PyFloat_FromDouble(p3.Z()));
|
||||
PyObject *points;
|
||||
if(flip)
|
||||
{
|
||||
points = PyTuple_Pack(3, t2, t1, t3);
|
||||
} else {
|
||||
points = PyTuple_Pack(3, t1, t2, t3);
|
||||
if (flip) {
|
||||
list.append(Py::asObject(PyTuple_Pack(3, t2, t1, t3)));
|
||||
}
|
||||
else {
|
||||
list.append(Py::asObject(PyTuple_Pack(3, t1, t2, t3)));
|
||||
}
|
||||
PyList_Append(list, points);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Py::asObject(list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
Py::Object makeCompound(const Py::Tuple& args)
|
||||
{
|
||||
|
||||
@@ -105,30 +105,31 @@ PyObject* FT2FC(const Py_UNICODE *PyUString,
|
||||
const size_t length,
|
||||
const char *FontSpec,
|
||||
const double stringheight, // fc coords
|
||||
const double tracking) { // fc coords
|
||||
FT_Library FTLib;
|
||||
FT_Face FTFont;
|
||||
FT_Error error;
|
||||
FT_Long FaceIndex = 0; // some fonts have multiple faces
|
||||
FT_Vector kern;
|
||||
FT_UInt FTLoadFlags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP;
|
||||
const double tracking) // fc coords
|
||||
{
|
||||
FT_Library FTLib;
|
||||
FT_Face FTFont;
|
||||
FT_Error error;
|
||||
FT_Long FaceIndex = 0; // some fonts have multiple faces
|
||||
FT_Vector kern;
|
||||
FT_UInt FTLoadFlags = FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP;
|
||||
|
||||
std::stringstream ErrorMsg;
|
||||
double PenPos = 0, scalefactor;
|
||||
UNICHAR prevchar = 0, currchar = 0;
|
||||
int cadv;
|
||||
size_t i;
|
||||
PyObject *WireList, *CharList;
|
||||
std::stringstream ErrorMsg;
|
||||
double PenPos = 0, scalefactor;
|
||||
UNICHAR prevchar = 0, currchar = 0;
|
||||
int cadv;
|
||||
size_t i;
|
||||
Py::List CharList;
|
||||
|
||||
error = FT_Init_FreeType(&FTLib);
|
||||
if(error) {
|
||||
ErrorMsg << "FT_Init_FreeType failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
error = FT_Init_FreeType(&FTLib);
|
||||
if (error) {
|
||||
ErrorMsg << "FT_Init_FreeType failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
|
||||
#ifdef FC_OS_WIN32
|
||||
Base::FileInfo fi(FontSpec);
|
||||
if (!fi.isReadable()) {
|
||||
if (!fi.isReadable()) {
|
||||
ErrorMsg << "Font file not found (Win): " << FontSpec;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
@@ -143,58 +144,61 @@ PyObject* FT2FC(const Py_UNICODE *PyUString,
|
||||
#endif
|
||||
|
||||
|
||||
error = FT_New_Face(FTLib,FontSpec,FaceIndex, &FTFont);
|
||||
if(error) {
|
||||
ErrorMsg << "FT_New_Face failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
error = FT_New_Face(FTLib,FontSpec,FaceIndex, &FTFont);
|
||||
if (error) {
|
||||
ErrorMsg << "FT_New_Face failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
|
||||
//TODO: check that FTFont is scalable? only relevant for hinting etc?
|
||||
|
||||
// FT2 blows up if char size is not set to some non-zero value.
|
||||
// This sets size to 48 point. Magic.
|
||||
error = FT_Set_Char_Size(FTFont,
|
||||
0, /* char_width in 1/64th of points */
|
||||
48*64, /* char_height in 1/64th of points */
|
||||
0, /* horizontal device resolution */
|
||||
0 ); /* vertical device resolution */
|
||||
if(error) {
|
||||
ErrorMsg << "FT_Set_Char_Size failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
error = FT_Set_Char_Size(FTFont,
|
||||
0, /* char_width in 1/64th of points */
|
||||
48*64, /* char_height in 1/64th of points */
|
||||
0, /* horizontal device resolution */
|
||||
0 ); /* vertical device resolution */
|
||||
if (error) {
|
||||
ErrorMsg << "FT_Set_Char_Size failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
|
||||
CharList = PyList_New(0);
|
||||
scalefactor = stringheight/float(FTFont->height);
|
||||
for (i=0; i<length; i++) {
|
||||
currchar = PyUString[i];
|
||||
error = FT_Load_Char(FTFont,
|
||||
currchar,
|
||||
FTLoadFlags);
|
||||
if(error) {
|
||||
ErrorMsg << "FT_Load_Char failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
scalefactor = stringheight/float(FTFont->height);
|
||||
for (i=0; i<length; i++) {
|
||||
currchar = PyUString[i];
|
||||
error = FT_Load_Char(FTFont,
|
||||
currchar,
|
||||
FTLoadFlags);
|
||||
if (error) {
|
||||
ErrorMsg << "FT_Load_Char failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
|
||||
cadv = FTFont->glyph->advance.x;
|
||||
kern = getKerning(FTFont,prevchar,currchar);
|
||||
PenPos += kern.x;
|
||||
WireList = getGlyphContours(FTFont,currchar,PenPos, scalefactor,i,tracking);
|
||||
if (!PyList_Size(WireList)) // empty ==> whitespace
|
||||
Base::Console().Log("FT2FC char '0x%04x'/'%d' has no Wires!\n", currchar, currchar);
|
||||
else
|
||||
PyList_Append(CharList, WireList);
|
||||
PenPos += cadv;
|
||||
prevchar = currchar;
|
||||
}
|
||||
cadv = FTFont->glyph->advance.x;
|
||||
kern = getKerning(FTFont,prevchar,currchar);
|
||||
PenPos += kern.x;
|
||||
try {
|
||||
Py::List WireList(getGlyphContours(FTFont, currchar, PenPos, scalefactor, i, tracking), true);
|
||||
CharList.append(WireList);
|
||||
}
|
||||
catch (Py::Exception& e) {
|
||||
e.clear();
|
||||
Base::Console().Log("FT2FC char '0x%04x'/'%d' has no Wires!\n", currchar, currchar);
|
||||
}
|
||||
|
||||
error = FT_Done_FreeType(FTLib);
|
||||
if(error) {
|
||||
ErrorMsg << "FT_Done_FreeType failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
PenPos += cadv;
|
||||
prevchar = currchar;
|
||||
}
|
||||
|
||||
return(CharList);
|
||||
}
|
||||
error = FT_Done_FreeType(FTLib);
|
||||
if (error) {
|
||||
ErrorMsg << "FT_Done_FreeType failed: " << error;
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
|
||||
return Py::new_reference_to(CharList);
|
||||
}
|
||||
|
||||
//********** FT Decompose callbacks and data defns
|
||||
// FT Decomp Context for 1 char
|
||||
@@ -342,7 +346,7 @@ PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, doub
|
||||
isTTF = true;
|
||||
}
|
||||
|
||||
PyObject* ret = PyList_New(0);
|
||||
Py::List list;
|
||||
|
||||
gp_Vec pointer = gp_Vec(PenPos * Scale + charNum*tracking,0.0,0.0);
|
||||
gp_Trsf xForm;
|
||||
@@ -372,9 +376,11 @@ PyObject* getGlyphContours(FT_Face FTFont, UNICHAR currchar, double PenPos, doub
|
||||
ErrorMsg << "FT2FC OCC BRepScale failed \n";
|
||||
throw std::runtime_error(ErrorMsg.str());
|
||||
}
|
||||
PyList_Append(ret,new TopoShapeWirePy(new TopoShape(TopoDS::Wire(BRepScale.Shape()))));
|
||||
|
||||
PyObject* wire = new TopoShapeWirePy(new TopoShape(TopoDS::Wire(BRepScale.Shape())));
|
||||
list.append(Py::asObject(wire));
|
||||
}
|
||||
return(ret);
|
||||
return Py::new_reference_to(list);
|
||||
}
|
||||
|
||||
// get kerning values for this char pair
|
||||
|
||||
@@ -2524,16 +2524,16 @@ PyObject* TopoShapePy::proximity(PyObject *args)
|
||||
PyObject* ps2;
|
||||
Standard_Real tol = Precision::Confusion();
|
||||
if (!PyArg_ParseTuple(args, "O!|d",&(TopoShapePy::Type), &ps2, &tol))
|
||||
return 0;
|
||||
return nullptr;
|
||||
const TopoDS_Shape& s1 = getTopoShapePtr()->getShape();
|
||||
const TopoDS_Shape& s2 = static_cast<Part::TopoShapePy*>(ps2)->getTopoShapePtr()->getShape();
|
||||
if (s1.IsNull()) {
|
||||
PyErr_SetString(PyExc_ValueError, "proximity: Shape object is invalid");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
if (s2.IsNull()) {
|
||||
PyErr_SetString(PyExc_ValueError, "proximity: Shape parameter is invalid");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
BRepExtrema_ShapeProximity proximity;
|
||||
@@ -2551,7 +2551,7 @@ PyObject* TopoShapePy::proximity(PyObject *args)
|
||||
BRep_Tool::Triangulation(TopoDS::Face(xp.Current()), aLoc);
|
||||
if (aTriangulation.IsNull()) {
|
||||
PyErr_SetString(PartExceptionOCCError, "BRepExtrema_ShapeProximity not done, call 'tessellate' beforehand");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2561,7 +2561,7 @@ PyObject* TopoShapePy::proximity(PyObject *args)
|
||||
BRep_Tool::Triangulation(TopoDS::Face(xp.Current()), aLoc);
|
||||
if (aTriangulation.IsNull()) {
|
||||
PyErr_SetString(PartExceptionOCCError, "BRepExtrema_ShapeProximity not done, call 'tessellate' beforehand");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2572,7 +2572,7 @@ PyObject* TopoShapePy::proximity(PyObject *args)
|
||||
BRep_Tool::Polygon3D(TopoDS::Edge(xp.Current()), aLoc);
|
||||
if (aPoly3D.IsNull()) {
|
||||
PyErr_SetString(PartExceptionOCCError, "BRepExtrema_ShapeProximity not done, call 'tessellate' beforehand");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2582,37 +2582,29 @@ PyObject* TopoShapePy::proximity(PyObject *args)
|
||||
BRep_Tool::Polygon3D(TopoDS::Edge(xp.Current()), aLoc);
|
||||
if (aPoly3D.IsNull()) {
|
||||
PyErr_SetString(PartExceptionOCCError, "BRepExtrema_ShapeProximity not done, call 'tessellate' beforehand");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// another problem must have occurred
|
||||
PyErr_SetString(PartExceptionOCCError, "BRepExtrema_ShapeProximity not done");
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
//PyObject* overlappss1 = PyList_New(0);
|
||||
//PyObject* overlappss2 = PyList_New(0);
|
||||
PyObject* overlappssindex1 = PyList_New(0);
|
||||
PyObject* overlappssindex2 = PyList_New(0);
|
||||
|
||||
Py::List overlappssindex1;
|
||||
Py::List overlappssindex2;
|
||||
|
||||
for (BRepExtrema_OverlappedSubShapes::Iterator anIt1 (proximity.OverlapSubShapes1()); anIt1.More(); anIt1.Next()) {
|
||||
//PyList_Append(overlappss1, new TopoShapeFacePy(new TopoShape(proximity.GetSubShape1 (anIt1.Key()))));
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyList_Append(overlappssindex1,PyLong_FromLong(anIt1.Key()+1));
|
||||
#else
|
||||
PyList_Append(overlappssindex1,PyInt_FromLong(anIt1.Key()+1));
|
||||
#endif
|
||||
overlappssindex1.append(Py::Long(anIt1.Key() + 1));
|
||||
}
|
||||
for (BRepExtrema_OverlappedSubShapes::Iterator anIt2 (proximity.OverlapSubShapes2()); anIt2.More(); anIt2.Next()) {
|
||||
//PyList_Append(overlappss2, new TopoShapeFacePy(new TopoShape(proximity.GetSubShape2 (anIt2.Key()))));
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyList_Append(overlappssindex2,PyLong_FromLong(anIt2.Key()+1));
|
||||
#else
|
||||
PyList_Append(overlappssindex2,PyInt_FromLong(anIt2.Key()+1));
|
||||
#endif
|
||||
overlappssindex2.append(Py::Long(anIt2.Key() + 1));
|
||||
}
|
||||
//return Py_BuildValue("OO", overlappss1, overlappss2); //subshapes
|
||||
return Py_BuildValue("OO", overlappssindex1, overlappssindex2); //face indexes
|
||||
|
||||
Py::Tuple tuple(2);
|
||||
tuple.setItem(0, overlappssindex1);
|
||||
tuple.setItem(1, overlappssindex2);
|
||||
return Py::new_reference_to(tuple); //face indexes
|
||||
#else
|
||||
(void)args;
|
||||
PyErr_SetString(PyExc_NotImplementedError, "proximity requires OCCT >= 6.8.1");
|
||||
|
||||
Reference in New Issue
Block a user