Skip to content

Commit

Permalink
More memory management fixes in pal, stack allocation rather than heap
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Nov 29, 2019
1 parent 6fdc99b commit 4351c30
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 59 deletions.
58 changes: 22 additions & 36 deletions src/core/pal/feature.cpp
Expand Up @@ -1404,8 +1404,6 @@ std::size_t FeaturePart::createCurvedCandidatesAlongLine( std::vector< std::uniq

std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_ptr< LabelPosition > > &lPos, PointSet *mapShape )
{
int j;

double labelWidth = getLabelWidth();
double labelHeight = getLabelHeight();

Expand All @@ -1428,23 +1426,20 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt
double px, py;
double dx;
double dy;
int bbid;
double beta;
double diago = std::sqrt( labelWidth * labelWidth / 4.0 + labelHeight * labelHeight / 4 );
double rx, ry;
CHullBox **boxes = new CHullBox*[shapes_final.size()];
j = 0;
std::vector< CHullBox > boxes;
boxes.reserve( shapes_final.size() );

// Compute bounding box foreach finalShape
while ( !shapes_final.isEmpty() )
{
PointSet *shape = shapes_final.takeFirst();
boxes[j] = shape->compute_chull_bbox();
boxes.emplace_back( shape->compute_chull_bbox() );

if ( shape->parent )
delete shape;

j++;
}

//dx = dy = min( yrm, xrm ) / 2;
Expand All @@ -1461,11 +1456,9 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt

do
{
for ( bbid = 0; bbid < j; bbid++ )
for ( CHullBox &box : boxes )
{
CHullBox *box = boxes[bbid];

if ( ( box->length * box->width ) > ( xmax - xmin ) * ( ymax - ymin ) * 5 )
if ( ( box.length * box.width ) > ( xmax - xmin ) * ( ymax - ymin ) * 5 )
{
// Very Large BBOX (should never occur)
continue;
Expand All @@ -1486,8 +1479,8 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt
if ( mLF->layer()->arrangement() == QgsPalLayerSettings::Free )
{
enoughPlace = true;
px = ( box->x[0] + box->x[2] ) / 2 - labelWidth;
py = ( box->y[0] + box->y[2] ) / 2 - labelHeight;
px = ( box.x[0] + box.x[2] ) / 2 - labelWidth;
py = ( box.y[0] + box.y[2] ) / 2 - labelHeight;
int i, j;

// Virtual label: center on bbox center, label size = 2x original size
Expand Down Expand Up @@ -1515,24 +1508,24 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt
{
alpha = 0.0; // HORIZ
}
else if ( box->length > 1.5 * labelWidth && box->width > 1.5 * labelWidth )
else if ( box.length > 1.5 * labelWidth && box.width > 1.5 * labelWidth )
{
if ( box->alpha <= M_PI_4 )
if ( box.alpha <= M_PI_4 )
{
alpha = box->alpha;
alpha = box.alpha;
}
else
{
alpha = box->alpha - M_PI_2;
alpha = box.alpha - M_PI_2;
}
}
else if ( box->length > box->width )
else if ( box.length > box.width )
{
alpha = box->alpha - M_PI_2;
alpha = box.alpha - M_PI_2;
}
else
{
alpha = box->alpha;
alpha = box.alpha;
}

beta = std::atan2( labelHeight, labelWidth ) + alpha;
Expand All @@ -1546,22 +1539,22 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt

double px0, py0;

px0 = box->width / 2.0;
py0 = box->length / 2.0;
px0 = box.width / 2.0;
py0 = box.length / 2.0;

px0 -= std::ceil( px0 / dx ) * dx;
py0 -= std::ceil( py0 / dy ) * dy;

for ( px = px0; px <= box->width; px += dx )
for ( px = px0; px <= box.width; px += dx )
{
for ( py = py0; py <= box->length; py += dy )
for ( py = py0; py <= box.length; py += dy )
{

rx = std::cos( box->alpha ) * px + std::cos( box->alpha - M_PI_2 ) * py;
ry = std::sin( box->alpha ) * px + std::sin( box->alpha - M_PI_2 ) * py;
rx = std::cos( box.alpha ) * px + std::cos( box.alpha - M_PI_2 ) * py;
ry = std::sin( box.alpha ) * px + std::sin( box.alpha - M_PI_2 ) * py;

rx += box->x[0];
ry += box->y[0];
rx += box.x[0];
ry += box.y[0];

bool candidateAcceptable = ( mLF->permissibleZonePrepared()
? GeomFunction::containsCandidate( mLF->permissibleZonePrepared(), rx - dlx, ry - dly, labelWidth, labelHeight, alpha )
Expand All @@ -1587,13 +1580,6 @@ std::size_t FeaturePart::createCandidatesForPolygon( std::vector< std::unique_pt
while ( nbp == 0 && numTry < maxTry );

nbp = numberCandidatesGenerated;

for ( bbid = 0; bbid < j; bbid++ )
{
delete boxes[bbid];
}

delete[] boxes;
}
else
{
Expand Down
37 changes: 18 additions & 19 deletions src/core/pal/pointset.cpp
Expand Up @@ -209,12 +209,11 @@ void PointSet::deleteCoords()
y.clear();
}

PointSet *PointSet::extractShape( int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty )
std::unique_ptr<PointSet> PointSet::extractShape( int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty )
{

int i, j;

PointSet *newShape = new PointSet();
std::unique_ptr<PointSet> newShape = qgis::make_unique< PointSet >();
newShape->type = GEOS_POLYGON;
newShape->nbPoints = nbPtSh;
newShape->x.resize( newShape->nbPoints );
Expand Down Expand Up @@ -272,8 +271,8 @@ bool PointSet::containsLabelCandidate( double x, double y, double width, double
return GeomFunction::containsCandidate( preparedGeom(), x, y, width, height, alpha );
}

void PointSet::splitPolygons( QLinkedList<PointSet *> &shapes_toProcess,
QLinkedList<PointSet *> &shapes_final,
void PointSet::splitPolygons( QLinkedList<PointSet *> &inputShapes,
QLinkedList<PointSet *> &outputShapes,
double xrm, double yrm )
{
int i, j;
Expand Down Expand Up @@ -313,9 +312,9 @@ void PointSet::splitPolygons( QLinkedList<PointSet *> &shapes_toProcess,

PointSet *shape = nullptr;

while ( !shapes_toProcess.isEmpty() )
while ( !inputShapes.isEmpty() )
{
shape = shapes_toProcess.takeFirst();
shape = inputShapes.takeFirst();

x = shape->x;
y = shape->y;
Expand Down Expand Up @@ -509,41 +508,41 @@ void PointSet::splitPolygons( QLinkedList<PointSet *> &shapes_toProcess,
// check for useless splitting
else if ( imax == imin || nbPtSh1 <= 2 || nbPtSh2 <= 2 || nbPtSh1 == nbp || nbPtSh2 == nbp )
{
shapes_final.append( shape );
outputShapes.append( shape );
}
else
{

PointSet *newShape = shape->extractShape( nbPtSh1, imin, imax, fps, fpe, fptx, fpty );
PointSet *newShape = shape->extractShape( nbPtSh1, imin, imax, fps, fpe, fptx, fpty ).release();

if ( shape->parent )
newShape->parent = shape->parent;
else
newShape->parent = shape;

shapes_toProcess.append( newShape );
inputShapes.append( newShape );

if ( imax == fps )
imax = fpe;
else
imax = fps;

newShape = shape->extractShape( nbPtSh2, imax, imin, fps, fpe, fptx, fpty );
newShape = shape->extractShape( nbPtSh2, imax, imin, fps, fpe, fptx, fpty ).release();

if ( shape->parent )
newShape->parent = shape->parent;
else
newShape->parent = shape;

shapes_toProcess.append( newShape );
inputShapes.append( newShape );

if ( shape->parent )
delete shape;
}
}
else
{
shapes_final.append( shape );
outputShapes.append( shape );
}
delete[] pts;
}
Expand Down Expand Up @@ -636,7 +635,7 @@ void PointSet::extendLineByDistance( double startDistance, double endDistance, d
invalidateGeos();
}

CHullBox *PointSet::compute_chull_bbox()
CHullBox PointSet::compute_chull_bbox()
{
int i;
int j;
Expand Down Expand Up @@ -768,18 +767,18 @@ CHullBox *PointSet::compute_chull_bbox()

// best bbox is defined

CHullBox *finalBb = new CHullBox();
CHullBox finalBb;

for ( i = 0; i < 16; i = i + 4 )
{
GeomFunction::computeLineIntersection( best_bb[i], best_bb[i + 1], best_bb[i + 2], best_bb[i + 3],
best_bb[( i + 4 ) % 16], best_bb[( i + 5 ) % 16], best_bb[( i + 6 ) % 16], best_bb[( i + 7 ) % 16],
&finalBb->x[int ( i / 4 )], &finalBb->y[int ( i / 4 )] );
&finalBb.x[int ( i / 4 )], &finalBb.y[int ( i / 4 )] );
}

finalBb->alpha = best_alpha;
finalBb->width = best_width;
finalBb->length = best_length;
finalBb.alpha = best_alpha;
finalBb.width = best_width;
finalBb.length = best_length;

return finalBb;
}
Expand Down
15 changes: 11 additions & 4 deletions src/core/pal/pointset.h
Expand Up @@ -80,7 +80,10 @@ namespace pal
PointSet( int nbPoints, double *x, double *y );
virtual ~PointSet();

PointSet *extractShape( int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty );
/**
* Does... something completely inscrutable.
*/
std::unique_ptr< PointSet > extractShape( int nbPtSh, int imin, int imax, int fps, int fpe, double fptx, double fpty );

/**
* Returns a copy of the point set.
Expand All @@ -106,13 +109,17 @@ namespace pal
*/
bool containsLabelCandidate( double x, double y, double width, double height, double alpha = 0 ) const;

CHullBox *compute_chull_bbox();
/**
* Computes a con???? hull. Maybe convex, maybe concave. The person who wrote this
* had no care for anyone else ever reading their code.
*/
CHullBox compute_chull_bbox();

/**
* Split a concave shape into several convex shapes.
*/
static void splitPolygons( QLinkedList<PointSet *> &shapes_toProcess,
QLinkedList<PointSet *> &shapes_final,
static void splitPolygons( QLinkedList<PointSet *> &inputShapes,
QLinkedList<PointSet *> &outputShapes,
double xrm, double yrm );

/**
Expand Down

0 comments on commit 4351c30

Please sign in to comment.